嗨,有没有办法做这样的事情:
for (int i = 0; i < Math.Min(a.Count, b.Count); i++)
{
// Do stuff
//a[i]
//b[i]
}
Run Code Online (Sandbox Code Playgroud)
与Foreach?
因为写一些类似的东西会很好
foreach(var item1 in list1 and var item2 in list2 /* ....*/)
{
item1.use(item2);
}
Run Code Online (Sandbox Code Playgroud)
好对不起我对某些人不够清楚,所以希望能有更好的解释
List<classA> listA = fillListA();
List<classB> listB = fillListB();
//here could be infinity many lists of sometimes diffrent T types
Run Code Online (Sandbox Code Playgroud)
现在我想执行某种ForEach因为我不喜欢用for循环做它应该简单明了很好像
foreach(var item1 in list1 and var item2 in list2 /* and ...*/)
{
item1.use(item2);
}
Run Code Online (Sandbox Code Playgroud)
AFAIK我不能修改这样一个keay词类的东西,所以我认为确定构建像Parallel.ForEach那样的迭代器,ForEach<TSource>(IEnumerable<TSource>, Action<TSource>)
但是我被卡住了因为我不知道如何实现它
Static.ForEach<TSource>(IEnumerable<TSource>,IEnumerable<TSource>, ???Action<TSource,???>????)
Run Code Online (Sandbox Code Playgroud)
Ere*_*mez 63
你可以做一些foreach
幕后工作,但有两个枚举器:
using(var e1 = list1.GetEnumerator())
using(var e2 = list2.GetEnumerator())
{
while(e1.MoveNext() && e2.MoveNext())
{
var item1 = e1.Current;
var item2 = e2.Current;
// use item1 and item2
}
}
Run Code Online (Sandbox Code Playgroud)
为方便起见,您可以编写如下的扩展方法来执行操作:
public static void ZipDo<T1, T2>( this IEnumerable<T1> first, IEnumerable<T2> second, Action<T1, T2> action)
{
using (var e1 = first.GetEnumerator())
using (var e2 = second.GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext())
{
action(e1.Current, e2.Current);
}
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它像:
list1.ZipDo(list2, (i1,i2) => i1.Use(i2));
Run Code Online (Sandbox Code Playgroud)
顺便说一句,你可以扩展它以使用3个或更多列表:
public static void ZipDo<T1, T2, T3>(this IEnumerable<T1> first,
IEnumerable<T2> second, IEnumerable<T3> third,
Action<T1, T2, T3> action)
{
using (var e1 = first.GetEnumerator())
using (var e2 = second.GetEnumerator())
using (var e3 = third.GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext() && e3.MoveNext())
{
action(e1.Current, e2.Current, e3.Current);
}
}
}
Run Code Online (Sandbox Code Playgroud)
当集合具有不同的泛型类型时,需要上述方法.但是,如果它们都具有相同的泛型类型,那么您可以编写一个带有任意数量IEnumerable<T>
s 的灵活方法:
public static void ZipAll<T>(this IEnumerable<IEnumerable<T>> all, Action<IEnumerable<T>> action)
{
var enumerators = all.Select(e => e.GetEnumerator()).ToList();
try
{
while (enumerators.All(e => e.MoveNext()))
action(enumerators.Select(e => e.Current));
}
finally
{
foreach (var e in enumerators)
e.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它:
var lists = new[] {
new[]{ 1, 1, 1 },
new[]{ 2, 2, 2 },
new[]{ 3, 3, 3 }};
lists.ZipAll(nums => Console.WriteLine(nums.Sum()));
// 6
// 6
// 6
Run Code Online (Sandbox Code Playgroud)
Ani*_*Ani 27
我能想到的唯一接近是Enumerable.Zip
沿元组:
foreach(var tuple in list1.Zip(list2, Tuple.Create))
{
tuple.Item1.use(tuple.Item2);
}
Run Code Online (Sandbox Code Playgroud)
当然,如果不是use
,我们有一个非副作用的方法,从两个元素产生第三个值,你可以这样做:
var result = list1.Zip(list2, (item1, item2) => item1.ProduceObject(item2))
.ToList(); // if required
Run Code Online (Sandbox Code Playgroud)
如果列表具有相同的长度,您也可以简单地使用局部整数变量:
List<classA> listA = fillListA();
List<classB> listB = fillListB();
var i = 0;
foreach(var itemA in listA)
{
itemA.use(listB[i++]);
}
Run Code Online (Sandbox Code Playgroud)