如何通过两个IEnumerables同时循环? [英] How to iterate through two IEnumerables simultaneously?

查看:109
本文介绍了如何通过两个IEnumerables同时循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要的enumerables 的IEnumerable< A> list1的的IEnumerable< B>列表2 ,并希望通过他们同时迭代,如:

I have to enumerables IEnumerable<A> list1 and IEnumerable<B> list2 and would like to iterate through them simultaneously like:

foreach((a, b) in (list1, list2)) {
  // use a and b
}

如果它们不包含相同数量的元素,一个异常应该抛出。

If they do not contain the same number of elements, an exception should be thrown.

什么是做到这一点的最好方法是什么?

What is the best way to do this?

推荐答案

下面是该操作的实现,通常被称为邮编:

Here's an implementation of this operation, typically called Zip:

using System;
using System.Collections.Generic;

namespace SO2721939
{
    public sealed class ZipEntry<T1, T2>
    {
        public ZipEntry(int index, T1 value1, T2 value2)
        {
            Index = index;
            Value1 = value1;
            Value2 = value2;
        }

        public int Index { get; private set; }
        public T1 Value1 { get; private set; }
        public T2 Value2 { get; private set; }
    }

    public static class EnumerableExtensions
    {
        public static IEnumerable<ZipEntry<T1, T2>> Zip<T1, T2>(
            this IEnumerable<T1> collection1, IEnumerable<T2> collection2)
        {
            if (collection1 == null)
                throw new ArgumentNullException("collection1");
            if (collection2 == null)
                throw new ArgumentNullException("collection2");

            int index = 0;
            using (IEnumerator<T1> enumerator1 = collection1.GetEnumerator())
            using (IEnumerator<T2> enumerator2 = collection2.GetEnumerator())
            {
                while (enumerator1.MoveNext() && enumerator2.MoveNext())
                {
                    yield return new ZipEntry<T1, T2>(
                        index, enumerator1.Current, enumerator2.Current);
                    index++;
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] numbers = new[] { 1, 2, 3, 4, 5 };
            string[] names = new[] { "Bob", "Alice", "Mark", "John", "Mary" };

            foreach (var entry in numbers.Zip(names))
            {
                Console.Out.WriteLine(entry.Index + ": "
                    + entry.Value1 + "-" + entry.Value2);
            }
        }
    }
}

要让它抛出一个异常,如果只是顺序的一个跑出来的价值观,改变while循环这样:

To make it throw an exception if just one of the sequences run out of values, change the while-loop so:

while (true)
{
    bool hasNext1 = enumerator1.MoveNext();
    bool hasNext2 = enumerator2.MoveNext();
    if (hasNext1 != hasNext2)
        throw new InvalidOperationException("One of the collections ran " +
            "out of values before the other");
    if (!hasNext1)
        break;

    yield return new ZipEntry<T1, T2>(
        index, enumerator1.Current, enumerator2.Current);
    index++;
}

这篇关于如何通过两个IEnumerables同时循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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