【问题标题】:How to rewrite cartesian product with LINQ如何用 LINQ 重写笛卡尔积
【发布时间】:2021-07-17 02:15:27
【问题描述】:

我有三个函数,一个使用来自 2 个数组的循环生成笛卡尔积,另一个使用来自 3 个数组的循环,以及一个使用 LINQ 和 2 个数组生成笛卡尔积。我想编写一个 LINQ 解决方案来获得 3 个数组。

        private static string[][] CartesianProductSmart(string[] arr1, string[] arr2)
        {
            // for each s1 in arr1, extract arr2, 
            // then pass s1 and s2 into a newly-made string array.
            return arr1.SelectMany(s1 => arr2, (s1, s2) => new string[] { s1, s2 })
                .ToArray();
        }
        private static string[][] CartesianProductDumb(string[] arr1, string[] arr2)
        {
            // the dumb way; nested foreach
            string[][] combos = new string[arr1.Length * arr2.Length][];

            int ii = 0;
            foreach (var strOne in arr1)
            {
                foreach (var strTwo in arr2)
                {
                    string[] combo = new string[2];

                    combo[0] = strOne;
                    combo[1] = strTwo;
                    combos[ii] = combo;

                    ii++;
                }
            }
            return combos;
        }
        private static string[][] CartesianProductDumbX3(string[] arr1, string[] arr2, string[] arr3)
        {
            // the dumb way; nested foreach
            string[][] combos = new string[arr1.Length * arr2.Length * arr3.Length][];

            int ii = 0;
            foreach (var strOne in arr1)
            {
                foreach (var strTwo in arr2)
                {
                    foreach (var strThree in arr3)
                    {
                        string[] combo = new string[3];

                        combo[0] = strOne;
                        combo[1] = strTwo;
                        combo[2] = strThree;
                        combos[ii] = combo;

                        ii++;
                    }
                }
            }

            return combos;
        }

前两个函数的行为相同 - 它们都返回 2 个数组的笛卡尔积。第三个是用三个数组做的,我怎样才能用 LINQ 重写那个函数? (最终我想写它以便我可以给它任何数组编号,但现在只有 3 就足够了。

【问题讨论】:

标签: c# arrays linq


【解决方案1】:

我不确定这是否是您要查找的内容,但它对我来说似乎是最简单和最易读的:

private static string[][] CartesianProductLinq(string[] arr1, string[] arr2,
    string[] arr3)
{
    return (from s1 in arr1
        from s2 in arr2
        from s3 in arr3
        select new[] {s1, s2, s3}).ToArray();
}

如果您更喜欢方法链语法,它可能类似于:

private static string[][] CartesianProductLinq(string[] arr1, string[] arr2, 
    string[] arr3)
{
    return arr1
        .SelectMany(s1 => arr2, (s1, s2) => new {s1, s2})
        .SelectMany(result => arr3, (result, s3) => new[] {result.s1, result.s2, s3})
        .ToArray();
}

请注意,方法名称已更改,因为 Linq 并非天生“聪明”,循环也并非天生“愚蠢”(在某些情况下,循环可能更有效)

【讨论】:

    猜你喜欢
    • 2013-03-29
    • 2021-05-06
    • 2016-11-22
    • 2012-02-24
    • 2011-09-18
    • 2014-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多