使用的foreach通过多个列表(语法糖)同时迭代多个、语法、迭代、列表

2023-09-04 02:33:28 作者:分镜头.

您好,有没有办法做这样的事情:

 的for(int i = 0; I< Math.Min(a.Count,b.Count);我++)
{
    //做的东西
    // A [1]
    //双]
}
 

用foreach?

,因为这将是很好写的东西像

(/ * ...... * / List1中和VAR项目2在list2中VAR ITEM1)

 的foreach
{
   item1.use(ITEM2);
}
 

修改

OK对不起,我不太清楚的一些人,所以我在这里希望能更好的解释

 名单,其中,CLASSA>为listA = fillListA();
名单< CLASSB>数组listB = fillListB();
//这里可以是无穷大很多,有时不同势性的T型名单
 
Spice语法是什么 Spice网表的语法详解和实例演示详细资料概述

现在我想执行某种的ForEach ,因为我不喜欢用的的循环做 它应该是简单明了以及像

(/ *和... *的/ var item1的List1中和VAR ITEM2在list2中)

 的foreach
{
    item1.use(ITEM2);
}
 

AFAIK我不能modifie这样的凯伊字类的东西 所以我想确定建立迭代器像Parallel.ForEach做的ForEach< TSource>(IEnumerable的< TSource>中动作< TSource>) 但她的我得到stucked,因为我不知道如何实现它

  Static.ForEach< TSource>(IEnumerable的< TSource>,IEnumerable的< TSource>中???动作< TSource,???> ????)
 

解决方案

您可以做什么的foreach 引擎盖下做,但是有两个调查员:

 使用(VAR E1 = list1.GetEnumerator())
使用(VAR E2 = list2.GetEnumerator())
{
    而(e1.MoveNext()&安培;&安培; e2.MoveNext())
    {
         VAR ITEM1 = e1.Current;
         VAR项目2 = e2.Current;

         //使用ITEM1和ITEM2
    }
}
 

为了方便起见,你可以写这样采取行动以下的扩展方法:

 公共静态无效ZipDo< T1,T2>(这IEnumerable的< T1>首先,IEnumerable的< T2>第二个,动作< T1,T2>动作)
{
    使用(VAR E1 = first.GetEnumerator())
    使用(VAR E2 = second.GetEnumerator())
    {
        而(e1.MoveNext()&安培;&安培; e2.MoveNext())
        {
            行动(e1.Current,e2.Current);
        }
    }
}
 

和使用它像:

  list1.ZipDo(list2中,(I1,I2)=> i1.Use(I2));
 

顺便说一句,你可以扩展为使用3个或更多列表:

 公共静态无效ZipDo< T1,T2,T3>(这IEnumerable的< T1>首先,
    IEnumerable的< T2>第二,IEnumerable的< T3>第三,
    动作< T1,T2,T3>行动)
{
    使用(VAR E1 = first.GetEnumerator())
    使用(VAR E2 = second.GetEnumerator())
    使用(VAR E3 = third.GetEnumerator())
    {
        而(e1.MoveNext()&安培;&安培; e2.MoveNext()&安培;&安培; e3.MoveNext())
        {
            行动(e1.Current,e2.Current,e3.Current);
        }
    }
}
 

上面的方法时,需要集合具有的不同的的泛型类型。但是,如果它们都具有的一样的泛型类型,那么你可以写一个灵活的方法,它采用任何数量的的IEnumerable&LT的; T> S:

 公共静态无效ZipAll< T>(这IEnumerable的< IEnumerable的< T>>全部动作< IEnumerable的< T>>动作)
{
    VAR枚举= all.Select(E => e.GetEnumerator())。了ToList();
    尝试
    {
        而(enumerators.All(E => e.MoveNext()))
            行动(enumerators.Select(E => e.Current));
    }
    最后
    {
        的foreach(在调查员变种E)
            e.Dispose();
    }
}
 

和使用它:

  VAR名单=新的[] {
     新[] {1,1,1},
     新的[] {2,2,2},
     新[] {3,3,3}};

lists.ZipAll(NUMS => Console.WriteLine(nums.Sum()));
// 6
// 6
// 6
 

Hi is there a way to do things like this:

for (int i = 0; i < Math.Min(a.Count, b.Count); i++)
{
    // Do stuff
    //a[i]
    //b[i]
}

with Foreach?

because it would be nice to write something like

foreach(var item1 in list1 and var item2 in list2 /* ....*/)
{
   item1.use(item2);
}

EDIT

ok sorry i wasn't clear enough for some people so here am hopefully better explanation

List<classA> listA = fillListA();
List<classB> listB = fillListB();
//here could be infinity many lists of sometimes diffrent T types

Now i want to perform some sort of ForEach because i dont like to do it with a for loop it should be simple and clear well something like

foreach(var item1 in list1 and var item2 in list2 /* and ...*/)
{
    item1.use(item2);
}

AFAIK i cant modifie such a keay word class thing so i thought ok build the iterator like Parallel.ForEach did ForEach<TSource>(IEnumerable<TSource>, Action<TSource>) but her i get stucked because i don't know how implement it

Static.ForEach<TSource>(IEnumerable<TSource>,IEnumerable<TSource>, ???Action<TSource,???>????)

解决方案

You can do what foreach does under the hood, but with two enumerators:

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
    }
}

For convenience, you can write an extension method like the following that takes an action:

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

and use it like:

list1.ZipDo(list2, (i1,i2) => i1.Use(i2));

By the way, you can expand this to use 3 or more lists:

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

The approach above is required when the collections have different generic types. However, if they all have the same generic type, then you can write a flexible method that takes any number of 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();
    }
}

and use it:

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

 
精彩推荐
图片推荐