C#迭代两个列表 - 可交换的内/外循环

时间:2017-02-15 18:20:42

标签: c# list loops foreach

我需要迭代三个列表并处理每个组合。最外层和第二层循环(list1 / list2)的顺序取决于某些排序规则。 此外,我在最后一个(list3)foreach循环之前和之后都有一些逻辑。 ProcesPair方法使用所有三个项目,并取决于他们的顺序。

        if (order == Order.Right)
        {
            foreach (var a in list1)
            {
                foreach (var b in list2)
                {
                    DoSomethingBefore();

                    foreach (var c in list3)
                    {
                        ProcessPair(a, b, c);
                    }

                    DoSomethingAfter();
                }
            }
        }
        else if (order == Order.Down)
        {
            foreach (var b in list2)
            {
                foreach (var a in list1)
                {
                    DoSomethingBefore();

                    foreach (var c in list3)
                    {
                        ProcessPair(a, b, c);
                    }

                    DoSomethingAfter();
                }
            }
        }

是否有可能让它更优雅?我知道,如何减少代码中的循环,比如Zip函数,但每个函数都相互匹配。

2 个答案:

答案 0 :(得分:2)

嵌套循环是LINQ SelectMany的指示符。因此,示例代码的等价物可能是这样的:

var pairs = 
    order == Order.Right ? list1.SelectMany(a => list2, (a, b) => new { a, b }) ?
    order == Order.Down ? list2.SelectMany(b => list1, (b, a) => new { a, b }) :
    null;

if (pairs != null)
{
    foreach (var pair in pairs)
    {
        DoSomethingBefore();
        foreach (var c in list3)
        {
            ProcessPair(pair.a, pair.b, c);
        }
        DoSomethingAfter();
    }
}

答案 1 :(得分:1)

或者只是将重复代码重构为一个单独的方法:

void ProcessPairs(List<int> list1, List<int> list2, List<int> list3)
{
    foreach (var a in list1)
        foreach (var b in list2)
        {
            DoSomethingBefore();

            foreach (var c in list3)
                ProcessPair(a, b, c);

            DoSomethingAfter();
        }        
}

然后

    if (order == Order.Right)
        ProcessPairs(list1, list2, list3);
    else if (order == Order.Down)
        ProcessPairs(list2, list1, list3);