如何用Linq或默认方案将同键异值字典转为匹配键元组列表?
可以用LINQ实现,这里提供几种方案
你的需求完全可以通过LINQ来实现,甚至能写出更简洁的代码,同时可根据性能需求选择不同写法:
1. 与原逻辑完全对齐的LINQ版本(性能和原循环一致)
这个写法和你原代码逻辑完全相同,通过TryGetValue避免两次字典查找,性能和原循环持平:
public static List<Tuple<TOut1, TOut2>> ParseToTupleList<TKey, TOut1, TOut2>( IDictionary<TKey, TOut1> a, IDictionary<TKey, TOut2> b) { return a.Select(kv => { if (b.TryGetValue(kv.Key, out var bVal)) return Tuple.Create(kv.Value, bVal); return null; }) .Where(tuple => tuple != null) .ToList(); }
2. 简洁的Join写法(大字典场景更高效)
如果两个字典数据量较大,使用Join会更高效——LINQ的Join内部会为第二个字典构建哈希索引,减少重复查找开销,最终结果和原逻辑一致(仅保留共同键的对应值):
public static List<Tuple<TOut1, TOut2>> ParseToTupleList<TKey, TOut1, TOut2>( IDictionary<TKey, TOut1> a, IDictionary<TKey, TOut2> b) { return a.Join(b, kvA => kvA.Key, // 从字典a中取键作为匹配依据 kvB => kvB.Key, // 从字典b中取键作为匹配依据 (kvA, kvB) => Tuple.Create(kvA.Value, kvB.Value)) // 匹配成功后生成元组 .ToList(); }
3. 简洁但性能略逊的写法(适合小字典场景)
如果字典数据量很小,追求极致简洁的话,可以用Where+Select的组合,但注意这种写法对每个匹配的键会做两次字典查找(ContainsKey和索引器访问),性能略差于前两种:
public static List<Tuple<TOut1, TOut2>> ParseToTupleList<TKey, TOut1, TOut2>( IDictionary<TKey, TOut1> a, IDictionary<TKey, TOut2> b) { return a.Where(kv => b.ContainsKey(kv.Key)) .Select(kv => Tuple.Create(kv.Value, b[kv.Key])) .ToList(); }
额外:用ValueTuple简化返回值(.NET Core/.NET 5+)
如果你的项目基于.NET Core或.NET 5及以上版本,可以用更轻量的ValueTuple替代传统Tuple,代码更简洁:
public static List<(TOut1, TOut2)> ParseToTupleList<TKey, TOut1, TOut2>( IDictionary<TKey, TOut1> a, IDictionary<TKey, TOut2> b) { return a.Where(kv => b.TryGetValue(kv.Key, out var bVal)) .Select(kv => (kv.Value, bVal)) .ToList(); }
内容的提问来源于stack exchange,提问作者Master Silver
相关产品推荐
相关产品推荐

