Использование Group by с x количеством элементов - PullRequest
0 голосов
/ 19 июня 2020

Вот список, представьте его как строки и столбцы, в которых строки идут вниз, а столбцы - в сторону. количество столбцов всегда будет одинаковым для всех строк.

      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 };

мой вопрос в том, как динамически группировать dataValues ​​по userParam, где user param - это n количество индекса. В приведенном выше примере он будет разделен на первый и третий столбцы. Однако индекс может измениться, и количество индексов также может измениться

пример

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

я знаю, как группировать, когда я знаю, сколько индексов будет (случай ниже 2 параметра индекса), однако, когда это динамика c (x сумма), тогда я не знаю, как это сделать

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

Ответы [ 2 ]

0 голосов
/ 19 июня 2020

Вы можете использовать Custom Comparer, чтобы добиться этого:
1 - Объявление GroupByComparer, которое наследуется от IEqualityComparer:

public class GroupByComparer : IEqualityComparer<List<string>>
{
    private static List<int> _intList;
    public GroupByComparer(List<int> intList)
    {
        _intList = intList;
    }
    public bool Equals(List<string> x, List<string> y)
    {
        foreach (int item in _intList)
        {
            if (x[item] != y[item])
                return false;
        }

        return true;
    }

    public int GetHashCode(List<string> obj)
    {
        int hashCode = 0;
        foreach (int item in _intList)
        {
            hashCode ^= obj[item].GetHashCode() + item;
        }

        return hashCode;
    }
}

2 - Группа вызовов с помощью EqualityComparer, например:

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

var result = dataValues.GroupBy(e => e, new GroupByComparer(userParam));

Надеюсь, вы найдете это полезным.

0 голосов
/ 19 июня 2020

Я считаю, что у меня что-то есть, но это выглядит медленно, дайте мне знать, есть ли что-то лучше для этого.

        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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...