以优先顺序将2个Linq序列合并为一个
我有2个序列,每个序列返回一个匿名类型,其中包含2个字段(称为x和y)。从语义上讲,x在这两个序列中充当键,y充当值以优先顺序将2个Linq序列合并为一个,linq,Linq,我有2个序列,每个序列返回一个匿名类型,其中包含2个字段(称为x和y)。从语义上讲,x在这两个序列中充当键,y充当值 如果两个序列中出现相同的x,那么如何指定第一个序列优先于第二个序列,从而将它们合并为一个序列?如果没有Linq,您可能会发现这样做更容易,但我的想法是这样的: var distinctWithPrecedence = seq1 .Concat(seq2) .GroupBy(i => i.x) .Select(g => g.First()); 如果Linq
如果两个序列中出现相同的x,那么如何指定第一个序列优先于第二个序列,从而将它们合并为一个序列?如果没有Linq,您可能会发现这样做更容易,但我的想法是这样的:
var distinctWithPrecedence = seq1
.Concat(seq2)
.GroupBy(i => i.x)
.Select(g => g.First());
如果Linq在幕后做的不多。基本思想是按关键分组。然后通过分组从每个元素中提取第一个元素。如果Linq的行为符合我的想法,那么第一个元素将是连接列表中的第一个元素,这意味着第一个序列具有先例
可能还有其他方法可以做到这一点,但这是我想到的第一个方法。我将从
var res = seq1.Union(seq2, Comparer);
但是Enumerable.Union
的文档没有指定从哪个序列中获取匹配元素,并且要求Comparer
是IEqualityComparer
的一个实现,如果TSource
是匿名类型,您就不会使用它(但可能值得具体说明)
否则,您需要实现自己的助手,例如:
IEnumerable<KeyValuePair<TKey, TValue>> Union(
this IEnumerable<KeyValuePair<TKey, TValue>> first,
IEnumerable<KeyValuePair<TKey, TValue>> second) {
var allFirst = first.ToDictionary(v => v.Key, v => v.Value);
foreach (var kv in allFirst) { yield return kv; }
foreach (var s in second) {
if (!allFirst.ContainsKey(s.Key)) {
yield return s;
}
}
IEnumerable并集(
这是第一次,
(可数秒){
var allFirst=first.ToDictionary(v=>v.Key,v=>v.Value);
foreach(var kv在allFirst中){yield return kv;}
foreach(第二个变量为s){
如果(!allFirst.ContainsKey(s.Key)){
收益率;
}
}
(如果要坚持使用自己的类型(属性x和y),可以在单个类型参数上使其成为泛型,但需要添加类型约束以允许访问单独的属性。)为了完整起见,我将注意到,
Union
确实指定了第一个
如果在第二个
中存在匹配元素,则“获胜”: