我一直在寻找一些快速有效的方法来合并数组中的项目。这是我的场景。集合按发件人排序。相邻元素不一定相差 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" });
我希望以前三个(这个数字可以变化,从至少 2 个元素到满足条件的尽可能多)元素成为一个元素的方式合并上述集合。不能合并不同类别的元素。
new Range() { From = 0, To = 5, Category = "AB" };
这样生成的集合总共有 4 个元素。
0 - 5 AB
6 - 8 CD
9 - 11 AB // no merging here, 12 is missing
13 - 15 AB
我有一个非常大的收藏,有超过 2.000.000 件元素,我希望尽可能高效。
最佳答案
这是一个通用的、可重复使用的解决方案,而不是一个临时的、特定的解决方案。 (根据评论更新)
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;
}
}
}
您必须提供方法来确定该项目是否可以合并,并合并它们。 这些确实应该是您的 Range 类的一部分,所以它会像它们一样被调用:
list.Merge((l,r)=> l.IsFollowedBy(r), (l,r)=> l.CombineWith(r));
如果你没有这些方法,那么你必须这样调用它:
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});
关于c# - 根据条件合并 IEnumerable 中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3487745/