() { new List() { "a", "b", "c", "d" }, new Li-6ren">
gpt4 book ai didi

c# - 如何将 "zip"或 "rotate"列为可变数量的列表?

转载 作者:可可西里 更新时间:2023-11-01 08:00:48 24 4
gpt4 key购买 nike

如果我有一个包含任意数量列表的列表,如下所示:

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" },
// ...etc...
};

...有没有办法以某种方式将列表“压缩”或“旋转”成这样的东西?

{ 
{ "a", "1", "w", ... },
{ "b", "2", "x", ... },
{ "c", "3", "y", ... },
{ "d", "4", "z", ... }
}

显而易见的解决方案是做这样的事情:

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 或其他方式?

最佳答案

您可以推出自己的 ZipMany 实例,手动迭代每个枚举。与在投影每个序列后使用 GroupBy 的那些相比,这可能在更大的序列上表现更好:

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();
}
}

关于c# - 如何将 "zip"或 "rotate"列为可变数量的列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17976823/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com