如何在.NET 2中同时迭代两个IEnumerables

时间:2011-02-03 15:42:56

标签: .net .net-2.0 foreach ienumerable

编辑:我将此分为两个问题:

  • 迭代两个以较短的列表结尾的列表
  • 迭代多个列表,直到达到最长列表的最后一个元素

假设我有两个IEnumerable,包含许多元素。每个IEnumerable都有另一种类型T.

IEnumerable<int> ints=getManyInts();
IEnumerable<string> strings=getSomeStrings();

我想要做的是迭代两个列表,并为每个步骤获取一个包含一个int和一个字符串的项目,直到达到最短列表的末尾。

for(Item<int,string> item in Foo.Combine<int,string>(ints, strings))
{
    int i=item.Val1;
    string s=item.Val2;
}

您还可以在.NET 4中提示如何执行此操作。

5 个答案:

答案 0 :(得分:5)

提示.NET 4.0:

var result = ints.Zip(strings, (i, s) => new { Key = i, Value = s });
foreach(var item in result)
{
    int key = item.Key;
    string value = item.Value;
    // Do something with the kvp
}

答案 1 :(得分:4)

作为非LINQ-apprach(.NET 2),这可以像这个顶级迭代一样完成,直到其中一个枚举完成:

using (IEnumerator<int> intItem = GetManyInts().GetEnumerator())
using (IEnumerator<string> stringItem = GetSomeStrings().GetEnumerator()) {
  while (intItem.MoveNext() && stringItem.MoveNext()) {
    int i=intItem.Current;
    string s=stringItem.Current;
  }
}

编辑(针对您的新情况),使用默认值进行迭代,直到最后一次枚举完成:

using (IEnumerator<int> intItem = GetManyInts().GetEnumerator())
using (IEnumerator<string> stringItem = GetSomeStrings().GetEnumerator()) {
  bool hasInt;
  bool hasString;
  while ((hasInt = intItem.MoveNext()) | (hasString = stringItem.MoveNext())) {
    int i=hasInt ? intItem.Current : default(int);
    string s=hasString ? stringItem.Current : default(string);
  }
}

答案 2 :(得分:1)

这可以通过手动执行for-each循环在内部执行的操作来完成

IEnumerable<int> ints=getManyInts();
IEnumerable<string> strings=getSomeStrings();
using (IEnumerator<int> intsEnum = ints.GetEnumerator())
using (IEnumerator<string> stringsEnum = strings.GetEnumerator())
{
    while (intsEnum.MoveNext() && stringsEnum.MoveNext())
    {
        int i = intsEnum.Current;
        string s = stringsEnum.Current;
    }
}

编辑最长名单:

IEnumerable<int> ints=getManyInts();
IEnumerable<string> strings=getSomeStrings();
using (IEnumerator<int> intsEnum = ints.GetEnumerator())
using (IEnumerator<string> stringsEnum = strings.GetEnumerator())
{
    bool intIsValid = intsEnum.MoveNext()
    bool stringIsValid = stringsEnum.MoveNext()
    while (intIsValid || stringIsValid)
    {
        int i = default(int)
        string s = default(string)
        if(intIsValid)
        {
           i = intsEnum.Current;
           intIsValid = intsEnum.MoveNext();
        }
        if(stringIsValid)
        {
           s = stringsEnum.Current;
           stringIsValid = stringsEnum.MoveNext();
        }
        //code goes here
    }
}

答案 3 :(得分:1)

答案 4 :(得分:0)

我不确定我是否理解问题/背景。

使用Dictionary会为你工作吗?

internal static class Foo
    {
        internal static Dictionary<TKey, TValue> Combine<TKey, TValue>
            ( IList<TKey> keys, IList<TValue> values )
        {
            var dictionary = new Dictionary<TKey, TValue>();
            // write your own 'combination' code...
            for (int i = 0; i < keys.Count && i<values.Count; i++)
            {
                dictionary.Add(keys[i], values[i]);
            }
            return dictionary;
        }
    }

    private static void Main(string[] args)
    {
        // collection initialization and var: .NET 3.0 or higher
        var keys = new List<int> {1, 2, 3, 5, 6, 7, 8, 10, 15, 99};
        var values = new List<string> {"one", "two", "tree", "four"};

        var combinded = Foo.Combine<int, string>(keys, values);
        foreach (KeyValuePair<int, string> keyValuePair in combinded)
        {
            int key = keyValuePair.Key;
            string value = keyValuePair.Value;
        }
    }