我有三个(可能有超过3-4个通用列表,但在这个例子中让3)通用列表.
List<string> list1
List<string> list2
List<string> list3
Run Code Online (Sandbox Code Playgroud)
所有列表都具有相同数量的元素(相同的计数).
我用它来组合两个ZIP列表:
var result = list1.Zip(list2, (a, b) => new {
test1 = f,
test2 = b
}
Run Code Online (Sandbox Code Playgroud)
我用它来foreach声明,以避免foreach每个List,就像
foreach(var item in result){
Console.WriteLine(item.test1 + " " + item.test2);
}
Run Code Online (Sandbox Code Playgroud)
如何在三个列表中使用带有Zip的simmilary?
谢谢
编辑:
我想要:
List<string> list1 = new List<string>{"test", "otherTest"};
List<string> list2 = new List<string>{"item", "otherItem"};
List<string> list3 = new List<string>{"value", "otherValue"};
Run Code Online (Sandbox Code Playgroud)
ZIP之后(我不知道方法),我想结果(在VS2010调试模式下)
[0] { a = {"test"},
b = {"item"},
c = {"value"}
}
[1] { a = {"otherTest"},
b = {"otherItem"},
c = {"otherValue"}
}
Run Code Online (Sandbox Code Playgroud)
怎么做 ?
Cri*_*scu 30
对我来说最明显的方法是使用Zip两次.
例如,
var results = l1.Zip(l2, (x, y) => x + y).Zip(l3, (x, y) => x + y);
Run Code Online (Sandbox Code Playgroud)
将组合(添加)三个List<int>对象的元素.
更新:
您可以定义一个新的扩展方法,其行为类似于Zip三个IEnumerables,如下所示:
public static class MyFunkyExtensions
{
public static IEnumerable<TResult> ZipThree<T1, T2, T3, TResult>(
this IEnumerable<T1> source,
IEnumerable<T2> second,
IEnumerable<T3> third,
Func<T1, T2, T3, TResult> func)
{
using (var e1 = source.GetEnumerator())
using (var e2 = second.GetEnumerator())
using (var e3 = third.GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext())
yield return func(e1.Current, e2.Current, e3.Current);
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法(与上述相同)现在变为:
var results = l1.ZipThree(l2, l3, (x, y, z) => x + y + z);
Run Code Online (Sandbox Code Playgroud)
同样,您现在可以将三个列表组合使用:
var results = list1.ZipThree(list2, list3, (a, b, c) => new { a, b, c });
Run Code Online (Sandbox Code Playgroud)
Nis*_*nga 14
.. 及其他Zip可用于生成包含来自三个指定序列的元素的元组序列。[文档]
var titles = new string[] { "Analyst", "Consultant", "Supervisor"};
var names = new string[] { "Adam", "Eve", "Michelle" };
var surnames = new string[] { "First", "Second", "Third" };
IEnumerable<(string Title, string Name, string Surname)> zip = titles.Zip(names, surnames);
Run Code Online (Sandbox Code Playgroud)
小智 5
我知道还有另一个非常有趣的解决方案。从教育的角度来看,这很有趣,但如果需要执行压缩不同数量的列表很多,那么它也可能有用。
此方法会覆盖 .NET 的 LINQSelectMany函数,当您使用 LINQ 的查询语法时,该函数由约定采用。标准SelectMany实现执行笛卡尔积。被覆盖的可以改为进行压缩。实际的实现可能是:
static IEnumerable<TResult> SelectMany<TSource, TCollection, TResult>(this IEnumerable<TSource> source,
Func<TSource, IEnumerable<TCollection>> selector, Func<TSource, TCollection, TResult> select)
{
using (var e1 = source.GetEnumerator())
using (var e2 = selector(default(TSource)).GetEnumerator())
while (true)
if (e1.MoveNext() && e2.MoveNext())
yield return select(e1.Current, e2.Current);
else
yield break;
}
Run Code Online (Sandbox Code Playgroud)
它看起来有点吓人,但它是一种压缩逻辑,如果编写一次,可以在很多地方使用,并且客户端的代码看起来很不错 - 您可以IEnumerable<T>使用标准 LINQ 查询语法压缩任意数量:
var titles = new string[] { "Analyst", "Consultant", "Supervisor"};
var names = new string[] { "Adam", "Eve", "Michelle" };
var surnames = new string[] { "First", "Second", "Third" };
var results =
from title in titles
from name in names
from surname in surnames
select $"{ title } { name } { surname }";
Run Code Online (Sandbox Code Playgroud)
如果然后执行:
foreach (var result in results)
Console.WriteLine(result);
Run Code Online (Sandbox Code Playgroud)
你会得到:
Analyst Adam First
Consultant Eve Second
Supervisor Michelle Third
Run Code Online (Sandbox Code Playgroud)
你应该在你的类中保持这个扩展是私有的,否则你会从根本上改变周围代码的行为。此外,新类型将非常有用,因此它不会与 IEnumerables 的标准 LINQ 行为发生冲突。
出于教育目的,我使用此扩展方法创建了一个小型 c# 项目 + 一些好处:https : //github.com/lukiasz/Zippable
另外,如果您觉得这很有趣,我强烈推荐Jon Skeet 的 Reimplementing LINQ to Objects 文章。
玩得开心!