首页 > 解决方案 > 使用带有 x 个元素的 Group by

问题描述

这是一个列表,可以将其视为行和列,其中行向下,列是侧向。所有行的列数始终相同。

      var dataValues = new List<List<string>>()
        {
            //row 1
            new List<string>(){"A","12","X","P8" },
            //row 2
            new List<string>(){"B","13","Y","P7" },
            //row 3
            new List<string>(){"C","12","Y","P6" },
            //row 4
            new List<string>(){"A","14","X","P5" },
            //....
            new List<string>(){"D","15","Z","P4" },
            new List<string>(){"A","13","X","P3" },
            new List<string>(){"B","14","Y","P2" },
            new List<string>(){"C","13","Z","P1" },
        };

用户提供要分组的索引列表。

var userParam= new List<int>() { 0, 2 };

我的问题是如何通过 userParam 对 dataValues 进行动态分组,其中用户参数是 n 个索引。在上面的示例中,它将按第一列和第三列分组。但是索引可以改变,索引的数量也可以改变

例子

var userParam2 = new List<int>() { 0, 2};
var userParam3 = new List<int>() { 0};
var userParam4 = new List<int>() { 0,1,2};

当我知道会有多少索引时,我知道如何分组(下面的情况是 2 个索引参数),但是当它是动态的(x 数量)时,我不知道该怎么做

 var result = dataValues.GroupBy(e => new { G1 = e[userParam2 [0]], G2 = e[userParam2 [1]] });

标签: c#linq

解决方案


我相信我有一些东西,但这看起来很慢,请让我知道是否有更好的方法。

        var userParams = new List<int>() { 0, 2 };

        var dataValues = new List<List<string>>()
        {
            new List<string>(){"A","12","X","P8" },
            new List<string>(){"B","13","Y","P7" },
            new List<string>(){"C","12","Y","P6" },
            new List<string>(){"A","14","X","P5" },
            new List<string>(){"D","15","Z","P4" },
            new List<string>(){"A","13","X","P3" },
            new List<string>(){"B","14","Y","P2" },
            new List<string>(){"C","13","Z","P1" },
        };

        var result = new List<(List<string> Key, List<List<string>> Values)>();
        result.Add((new List<string>(), dataValues));

        for (int index = 0; index < userParams.Count; index++)
        {
            var currentResult = new List<(List<string> Key, List<List<string>> Values)>();
            foreach (var item in result)
            {
                foreach (var newGroup in item.Values.GroupBy(e => e[userParams[index]]))
                {
                    var newKey = item.Key.ToList();
                    newKey.Add(newGroup.Key);
                    currentResult.Add((newKey, newGroup.ToList()));
                }
            }
            result = currentResult;
        }

            foreach(var res in result)
            {
                Console.WriteLine($"Key: {string.Join(@"\", res.Key)}, Values: {string.Join(" | ", res.Values.Select(e=> string.Join(",",e)))}");
            }

最后结果

Key: A\X, Values: A,12,X,P8 | A,14,X,P5 | A,13,X,P3
Key: B\Y, Values: B,13,Y,P7 | B,14,Y,P2
Key: C\Y, Values: C,12,Y,P6
Key: C\Z, Values: C,13,Z,P1
Key: D\Z, Values: D,15,Z,P4

推荐阅读