在Linq(C#)中将多个不同大小的集合动态交叉连接在一起

栏目: ASP.NET · 发布时间: 7年前

内容简介:我有一个未知数量的桶(集合),每个桶具有未知数量的实体我需要生成所有实体的笛卡尔积,这样我最终得到一个具有ARRAYS实体的COLLECTION,并且在每个数组中,每个桶都有1个代表性.因此,如果我有5个桶(B1..B5),并且桶B1,B2各有1个项目,而桶B3,B4和B5各有4个,8个和10个项目,我将收集320个数组,每个数组将有5个项目.

我有一个未知数量的桶(集合),每个桶具有未知数量的实体

我需要生成所有实体的笛卡尔积,这样我最终得到一个具有ARRAYS实体的COLLECTION,并且在每个数组中,每个桶都有1个代表性.

因此,如果我有5个桶(B1..B5),并且桶B1,B2各有1个项目,而桶B3,B4和B5各有4个,8个和10个项目,我将收集320个数组,每个数组将有5个项目.

这里唯一的麻烦问题是,在开发时,桶的大小和桶的数量都是未知的.

性能在这里并不是非常重要,因为在大多数情况下,我的桶只有1个实体,而且很少有时候我的桶会包含20-30个项目…而且我通常会有5个30桶

我想在某种程度上利用linq,但是当我试图想象这是如何工作的时候,我的大脑正在变得油腻

您可以创建如下的扩展方法:

public static class EnumerableExtensions
{
    public static IEnumerable<TValue []> Permutations<TKey, TValue>(this IEnumerable<TKey> keys, Func<TKey, IEnumerable<TValue>> selector)
    {
        var keyArray = keys.ToArray();
        if (keyArray.Length < 1)
            yield break;
        TValue [] values = new TValue[keyArray.Length];
        foreach (var array in Permutations(keyArray, 0, selector, values))
            yield return array;
    }

    static IEnumerable<TValue []> Permutations<TKey, TValue>(TKey [] keys, int index, Func<TKey, IEnumerable<TValue>> selector, TValue [] values)
    {
        Debug.Assert(keys.Length == values.Length);

        var key = keys[index];
        foreach (var value in selector(key))
        {
            values[index] = value;
            if (index < keys.Length - 1)
            {
                foreach (var array in Permutations(keys, index+1, selector, values))
                    yield return array;
            }
            else
            {
                yield return values.ToArray(); // Clone the array;
            }
        }
    }
}

例如,它可以像:

public static void TestPermutations()
    {
        int [][] seqence = new int [][]
        {
            new int [] {1, 2, 3},
            new int [] {101},
            new int [] {201},
            new int [] {301, 302, 303},
        };

        foreach (var array in seqence.Permutations(a => a))
        {
            Debug.WriteLine(array.Aggregate(new StringBuilder(), (sb, i) => { if (sb.Length > 0) sb.Append(","); sb.Append(i); return sb; }));
        }
    }

并产生以下输出:

1,101,201,301
1,101,201,302
1,101,201,303
2,101,201,301
2,101,201,302
2,101,201,303
3,101,201,301
3,101,201,302
3,101,201,303

那是你要的吗?

翻译自:https://stackoverflow.com/questions/27328235/dynamically-cross-join-multiple-different-size-collections-together-in-linq-c


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

从颠覆到创新

从颠覆到创新

长江商学院 / 中国友谊出版公司 / 49.00

互联网+时代的汹涌来临,一切我们所熟知的事物都在发生改变,商业模式的剧烈变化正在席卷各行各业,所有坚硬的壁垒都将消散,所有的企业都面临着商业模式的再探索和转型,而商业模式的探索、失败、进化,甚而再回到起点,杀死自己推倒重来,不断颠覆不断创新,不断涅槃不断重生,这不仅仅是这个时代新创公司的特征,也是今天互联网领域所有存活下来的巨头们的轨迹。 本书通过11个典型的互联网企业商业模式转型案例,讲述......一起来看看 《从颠覆到创新》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具