【问题标题】:Merging two IEnumerable<T>s合并两个 IEnumerable<T>
【发布时间】: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);  
}

有什么建议吗?

【问题讨论】:

    标签: c# merge


    【解决方案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。作为“幕后”,它可以重新连接到数据库或对每个枚举进行一些计算。或者,说,只是无限......
      猜你喜欢
      • 2020-09-23
      • 1970-01-01
      • 2012-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多