如何与QUOT;拉链"或QUOT;转"可变数目的列表? [英] How to "zip" or "rotate" a variable number of lists?
本文介绍了如何与QUOT;拉链"或QUOT;转"可变数目的列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
如果我有一个包含列表任意数量的列表,像这样:
If I have a list containing an arbitrary number of lists, like so:
var myList = new List<List<string>>()
{
new List<string>() { "a", "b", "c", "d" },
new List<string>() { "1", "2", "3", "4" },
new List<string>() { "w", "x", "y", "z" }
};
...有没有办法以某种方式压缩或旋转列表弄成这样?
...is there any way to somehow "zip" or "rotate" the lists into something like this?
{
{ "a", "1", "w" },
{ "b", "2", "x" },
{ "c", "3", "y" },
{ "d", "4", "z" }
}
显而易见的解决办法是做这样的事情:
The obvious solution would be to do something like this:
public static IEnumerable<IEnumerable<T>> Rotate<T>(this IEnumerable<IEnumerable<T>> list)
{
for (int i = 0; i < list.Min(x => x.Count()); i++)
{
yield return list.Select(x => x.ElementAt(i));
}
}
// snip
var newList = myList.Rotate();
...但我不知道是否有这样做的更清洁的方式,使用LINQ或以其他方式?
...but I was wondering if there was a cleaner way of doing so, using linq or otherwise?
推荐答案
您可以推出自己的ZipMany实例,手动遍历每个枚举。比那些使用在较大序列这可能会表现得更好 GROUPBY
投影每个序列之后:
You can roll your own ZipMany instance which manually iterates each of the enumerations. This will likely perform better on larger sequences than those using GroupBy
after projecting each sequence:
public static IEnumerable<TResult> ZipMany<TSource, TResult>(
IEnumerable<IEnumerable<TSource>> source,
Func<IEnumerable<TSource>, TResult> selector)
{
// ToList is necessary to avoid deferred execution
var enumerators = source.Select(seq => seq.GetEnumerator()).ToList();
try
{
while (true)
{
foreach (var e in enumerators)
{
bool b = e.MoveNext();
if (!b) yield break;
}
// Again, ToList (or ToArray) is necessary to avoid deferred execution
yield return selector(enumerators.Select(e => e.Current).ToList());
}
}
finally
{
foreach (var e in enumerators)
e.Dispose();
}
}
这篇关于如何与QUOT;拉链&QUOT;或QUOT;转&QUOT;可变数目的列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文