根据条件合并IEnumerable中的元素

Tom*_*ski 2 .net c# algorithm collections

我正在寻找一些快速有效的方法来合并数组中的项目.这是我的情景.该集合按From排序.相邻元素不一定相差1,即最后一个To和下一个From之间可能存在间隙,但它们从不重叠.

var list = new List<Range>();
list.Add(new Range() { From = 0, To = 1, Category = "AB" });
list.Add(new Range() { From = 2, To = 3, Category = "AB" });
list.Add(new Range() { From = 4, To = 5, Category = "AB" });
list.Add(new Range() { From = 6, To = 8, Category = "CD" });
list.Add(new Range() { From = 9, To = 11, Category = "AB" }); // 12 is missing, this is ok
list.Add(new Range() { From = 13, To = 15, Category = "AB" });
Run Code Online (Sandbox Code Playgroud)

我希望上面的集合以这样的方式合并:前三个(这个数字可以变化,从至少2个元素变化到满足条件的数量)元素成为一个元素.无法合并具有不同类别的元素.

new Range() { From = 0, To = 5, Category = "AB" };
Run Code Online (Sandbox Code Playgroud)

这样得到的集合总共有4个元素.

0 - 5    AB
6 - 8    CD
9 - 11   AB // no merging here, 12 is missing
13 - 15  AB
Run Code Online (Sandbox Code Playgroud)

我有一个非常大的集合,超过2.000.000项目,我希望尽可能高效.

Jam*_*ran 5

这是一个通用的,可重用的解决方案,而不是特定的特定解决方案.(根据评论更新)

IEnumerable<T> Merge<T>(this IEnumerable<T> coll, 
                      Func<T,T,bool> canBeMerged, Func<T,T,T>mergeItems)
{
    using(IEnumerator<T> iter = col.GetEnumerator())
    {
      if (iter.MoveNext())
      {
          T lhs = iter.Current;
          while(iter.MoveNext())
          {
              T rhs = iter.Current;
              if (canBeMerged(lhs, rhs)
                 lhs=mergeItems(lhs, rhs);
              else
              {
                 yield return lhs;
                 lhs= rhs;
              }
          }
          yield return lhs;
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

您必须提供方法来确定是否可以合并项目并合并它们.这些应该是Range类的一部分,所以它会像它们一样被调用:

list.Merge((l,r)=> l.IsFollowedBy(r), (l,r)=> l.CombineWith(r));
Run Code Online (Sandbox Code Playgroud)

如果您没有这些方法,那么您必须将其称为:

list.Merge((l,r)=> l.Category==r.Category && l.To +1 == r.From,
           (l,r)=> new Range(){From = l.From, To=r.To, Category = l.Category});
Run Code Online (Sandbox Code Playgroud)