如果我有,例如以下 List<int>
{ 1, 2, 3, 4 } //list1
{ 2, 3, 5, 6 } //list2
...
{ 3, 4, 5 } //listN
检索以下对应的List<int?>
的最佳方法是什么?是吗?
{ 1, 2, 3, 4, null, null } //list1
{ null, 2, 3, null, 5, 6 } //list2
...
{ null, null, 3, 4, 5, null } //listN
最佳答案
我正在发布我们在聊天中讨论的解决方案。我有一个未优化的版本,使用 Linq 进行循环/过滤:
- http://ideone.com/H4gCoE (现场演示)
但是,我怀疑它不会太高效,因为创建了所有枚举器类,并且在此过程中实例化/修改了集合。
所以我花时间优化它到手写的循环与管理跟踪活跃的迭代器而不是修改iters
收藏。在这里:
参见 http://ideone.com/FuZIDy 完整的现场演示。
Note I assume the lists are pre-ordered by
DefaultComparer<T>
, since I use Linq'sMin()
extension method without a custom comparer
public static IEnumerable<IEnumerable<T>> AlignSequences<T>(this IEnumerable<IEnumerable<T>> sequences)
{
var iters = sequences
.Select((s, index) => new { active=true, index, enumerator = s.GetEnumerator() })
.ToArray();
var isActive = iters.Select(it => it.enumerator.MoveNext()).ToArray();
var numactive = isActive.Count(flag => flag);
try
{
while (numactive > 0)
{
T min = iters
.Where(it => isActive[it.index])
.Min(it => it.enumerator.Current);
var row = new T[iters.Count()];
for (int j = 0; j < isActive.Length; j++)
{
if (!isActive[j] || !Equals(iters[j].enumerator.Current, min))
continue;
row[j] = min;
if (!iters[j].enumerator.MoveNext())
{
isActive[j] = false;
numactive -= 1;
}
}
yield return row;
}
}
finally
{
foreach (var iter in iters) iter.enumerator.Dispose();
}
}
像这样使用它:
public static void Main(string[] args)
{
var list1 = new int?[] { 1, 2, 3, 4, 5 };
var list2 = new int?[] { 3, 4, 5, 6, 7 };
var list3 = new int?[] { 6, 9, 9 };
var lockstep = AlignSequences(new[] { list1, list2, list3 });
foreach (var step in lockstep)
Console.WriteLine(string.Join("\t", step.Select(i => i.HasValue ? i.Value.ToString() : "null").ToArray()));
}
它打印(出于演示目的,我横向打印结果):
1 null null
2 null null
3 3 null
4 4 null
5 5 null
null 6 6
null 7 null
null null 9
null null 9
注意:您可能希望更改界面以接受任意数量的列表,而不是单个序列序列:
public static IEnumerable<IEnumerable<T>> AlignSequences<T>(params IEnumerable<T>[] sequences)
这样你就可以调用
var lockstep = AlignSequences(list1, list2, list3);
关于c# - 对齐多个排序列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13513789/