如何使用单个foreach遍历相同长度的两个集合 [英] How to iterate through two collections of the same length using a single foreach

查看:91
本文介绍了如何使用单个foreach遍历相同长度的两个集合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这个问题之前已经问过很多次了,但是我尝试了答案,但似乎没有用.

我有两个长度相同但类型不同的列表,并且当 list1 [i] 连接到 list2 [时,我想同时遍历这两个列表.[i] .

例如:

假设我有list1(如 List< string> )和list2(如 List< int> )

我想做

  foreach(变量listitem1,list1,list2中的listitem2){//做东西} 

这可能吗?

解决方案

编辑-在两个集合中定位在相同索引处进行迭代

如果要求以同步"方式遍历两个集合,即将第一个集合的第一个元素与第二个集合的第一个元素一起使用,则将第二个和第二个元素一起使用,依此类推,以此类推,而无需执行任何副作用代码,然后查看 @sll的答案,并使用 .Zip()进行投影用相同的索引对成对的元素,直到其中一个集合用完了元素.

更一般的

代替 foreach ,您可以使用 GetEnumerator()

从两个集合的 IEnumerable 中访问 IEnumerator .code>方法,然后在需要移至该集合中的下一个元素时调用该集合上的 MoveNext().在处理两个或更多有序流而无需实现流时,此技术很常见.

  var stream1Enumerator = stream1.GetEnumerator();var stream2Enumerator = stream2.GetEnumerator();var currentGroupId = -1;//初始值//,即直到stream1Enumerator耗尽同时(stream1Enumerator.MoveNext()){//现在,您可以独立地迭代集合如果(stream1Enumerator.Current.Id!= currentGroupId){stream2Enumerator.MoveNext();currentGroupId = stream2Enumerator.Current.Id;}//使用stream1Enumerator.Current和stream2Enumerator.Current进行操作} 

正如其他人指出的那样,如果集合已实现并且支持索引,例如 ICollection 接口,则也可以使用下标 [] 运算符,尽管如今感觉很笨拙:

  var minimumUpperBound = Math.Min(collection1.Count,collection2.Count);对于(var index = 0; index< minimumUpperBound; index ++){//对collection1 [index]和collection2 [index]进行操作} 

最后,还有一个超载Linq的 .Select() 的一部分,它提供了返回的元素的索引序号,这也可能有用.

例如下面将把 collection1 的所有元素与 collection2 的前两个元素配对:

  var AlternativePairs = collection1.Select((item1,index1)=>新的{项目1 =项目1,项目2 =集合2 [索引1%2]}); 

I know this question has been asked many times before but I tried out the answers and they don't seem to work.

I have two lists of the same length but not the same type, and I want to iterate through both of them at the same time as list1[i] is connected to list2[i].

Eg:

Assuming that i have list1 (as List<string>) and list2 (as List<int>)

I want to do something like

foreach( var listitem1, listitem2 in list1, list2)
{
   // do stuff
}

Is this possible?

解决方案

Edit - Iterating whilst positioning at the same index in both collections

If the requirement is to move through both collections in a 'synchronized' fashion, i.e. to use the 1st element of the first collection with the 1st element of the second collection, then 2nd with 2nd, and so on, without needing to perform any side effecting code, then see @sll's answer and use .Zip() to project out pairs of elements at the same index, until one of the collections runs out of elements.

More Generally

Instead of the foreach, you can access the IEnumerator from the IEnumerable of both collections using the GetEnumerator() method and then call MoveNext() on the collection when you need to move on to the next element in that collection. This technique is common when processing two or more ordered streams, without needing to materialize the streams.

var stream1Enumerator = stream1.GetEnumerator();
var stream2Enumerator = stream2.GetEnumerator();
var currentGroupId = -1; // Initial value
// i.e. Until stream1Enumerator runs out of 
while (stream1Enumerator.MoveNext())
{
   // Now you can iterate the collections independently
   if (stream1Enumerator.Current.Id != currentGroupId)
   {
       stream2Enumerator.MoveNext();
       currentGroupId = stream2Enumerator.Current.Id;
   }
   // Do something with stream1Enumerator.Current and stream2Enumerator.Current
}

As others have pointed out, if the collections are materialized and support indexing, such as an ICollection interface, you can also use the subscript [] operator, although this feels rather clumsy nowadays:

var smallestUpperBound = Math.Min(collection1.Count, collection2.Count);
for (var index = 0; index < smallestUpperBound; index++)
{
     // Do something with collection1[index] and collection2[index]
}

Finally, there is also an overload of Linq's .Select() which provides the index ordinal of the element returned, which could also be useful.

e.g. the below will pair up all elements of collection1 alternatively with the first two elements of collection2:

var alternatePairs = collection1.Select(
    (item1, index1) => new 
    {
        Item1 = item1,
        Item2 = collection2[index1 % 2]
    });

这篇关于如何使用单个foreach遍历相同长度的两个集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆