合并两个 IEnumerable<T>

Posted

技术标签:

【中文标题】合并两个 IEnumerable<T>【英文标题】:Merging two IEnumerable<T>s 【发布时间】:2010-10-10 02:41:02 【问题描述】:

我有两个IEnumerable&lt;T&gt;s。

一个被后备元素填充。这将始终包含最多的元素。 另一个将根据某些参数被填充,并且可能包含更少的元素。 如果第二个元素中不存在某个元素,我需要用第一个元素的等效元素填充它。

这段代码完成了这项工作,但我觉得效率低下,需要我将 IEnumerables 强制转换为 ILists 或使用临时列表 Person 实现 IEquatable

IEnumerable<Person> fallBack = Repository.GetPersons();
IList<Person> translated = Repository.GetPersons(language).ToList();

foreach (Person person in fallBack)

    if (!translated.Any(p=>p.equals(person)))
        translated.add(person);  

有什么建议吗?

【问题讨论】:

【参考方案1】:

使用ConcatUnionList&lt;dynamic&gt; 类型的情况下不起作用

【讨论】:

【参考方案2】:
translated.Union(fallback)

或者(如果 Person 没有通过 ID 实现 IEquatable&lt;Person&gt;

translated.Union(fallback, PersonComparer.Instance)

PersonComparer 在哪里:

public class PersonComparer : IEqualityComparer<Person>

    public static readonly PersonComparer Instance = new PersonComparer();

    // We don't need any more instances
    private PersonComparer() 

    public int GetHashCode(Person p)
    
        return p.id;
    

    public bool Equals(Person p1, Person p2)
    
        if (Object.ReferenceEquals(p1, p2))
        
            return true;
        
        if (Object.ReferenceEquals(p1, null) ||
            Object.ReferenceEquals(p2, null))
        
            return false;
        
        return p1.id == p2.id;
    

【讨论】:

只有在 Person 类正确实现 Equality 时才会起作用。从 OP 来看,我猜他们没有。 哈哈!乔恩,你不能把它包装成更多的笨蛋吗?我再次感到完全愚蠢:P 实际上是这样。 OP 也不包含真正的代码。部分是因为它简化了我的问题,部分是因为我的老板害怕将代码放在公共区域:s @Jared:我到了 :) 实际上,我担心这似乎不是我想要的解决方案。这将为我提供包含其中所有元素的集合,并且它永远不会命中我的 Equals(Person other) 方法。我做错了什么还是我的问题传达错误?【参考方案3】:

试试这个。

public static IEnumerable<Person> SmartCombine(IEnumerable<Person> fallback, IEnumerable<Person> translated) 
  return translated.Concat(fallback.Where(p => !translated.Any(x => x.id.equals(p.id)));

【讨论】:

这很好用,但您必须注意一个问题:programmaticallyspeaking.com/… 我会避免多次使用 IEnumerable。作为“幕后”,它可以重新连接到数据库或对每个枚举进行一些计算。或者,说,只是无限......

以上是关于合并两个 IEnumerable<T>的主要内容,如果未能解决你的问题,请参考以下文章

如何将两个 IEnumerable<T> 连接成一个新的 IEnumerable<T>?

Parallel.ForEach() 与 foreach(IEnumerable<T>.AsParallel())

将 IEnumerable<Ienumerable<T>> 转换为 Dictionary<key,IEnumerable<T>>

SelectMany 和 Select的区别

无法将类型“IEnumerable<T>”隐式转换为“ActionResult<IEnumerable<T>>”

如何将多个 IEnumerable<IEnumerable<T>> 列表添加到 IEnumerable<List<int>>