【发布时间】:2022-03-11 23:56:55
【问题描述】:
我有几个巨大的要合并的可枚举序列。这些列表被处理为IEnumerable,但已经排序。由于输入列表已排序,因此应该可以在一次行程中合并它们,而无需重新排序。
我想保留延迟执行的行为。
我试图编写一个简单的算法来做到这一点(见下文)。但是,它看起来很丑陋,我相信它可以优化。它可能存在更学术的算法...
IEnumerable<T> MergeOrderedLists<T, TOrder>(IEnumerable<IEnumerable<T>> orderedlists,
Func<T, TOrder> orderBy)
{
var enumerators = orderedlists.ToDictionary(l => l.GetEnumerator(), l => default(T));
IEnumerator<T> tag = null;
var firstRun = true;
while (true)
{
var toRemove = new List<IEnumerator<T>>();
var toAdd = new List<KeyValuePair<IEnumerator<T>, T>>();
foreach (var pair in enumerators.Where(pair => firstRun || tag == pair.Key))
{
if (pair.Key.MoveNext())
toAdd.Add(pair);
else
toRemove.Add(pair.Key);
}
foreach (var enumerator in toRemove)
enumerators.Remove(enumerator);
foreach (var pair in toAdd)
enumerators[pair.Key] = pair.Key.Current;
if (enumerators.Count == 0)
yield break;
var min = enumerators.OrderBy(t => orderBy(t.Value)).FirstOrDefault();
tag = min.Key;
yield return min.Value;
firstRun = false;
}
}
方法可以这样使用:
// Person lists are already sorted by age
MergeOrderedLists(orderedList, p => p.Age);
假设以下Person 类存在于某处:
public class Person
{
public int Age { get; set; }
}
应该保留重复,我们不关心它们在新序列中的顺序。您看到我可以使用的任何明显优化吗?
【问题讨论】:
标签: c# linq performance algorithm optimization