Подсчет элементов из кортежа с запятой - PullRequest
1 голос
/ 18 июня 2019

У меня есть List<Tuple<string, string>>, который имеет следующие данные:

var intents = new List<Tuple<string, string>>
{
    new Tuple<string, string>("60b0e926-2f3a-458d-91f7-fe4a21f1c0f1",
        "Options ,Options ,Options ,Options ,Options ,Options ,Options ,Options ," +
        "Options ,Options ,Options ,Options ,Options"),
    new Tuple<string, string>("d463d996-78cc-428e-8a76-e4875e1c8ff4",
        "RescheudleApt ,RescheudleApt ,ConfirmApt ,ConfirmApt ," + 
        "RescheudleApt ,RescheudleApt"),
    new Tuple<string, string>("re80e926-2f3a-458d-91f7-fe4a54f1c0f1", "ConfirmAppt"),
};

Желаемый вывод для будет примерно таким:

60b0e926-2f3a-458d-91f7-fe4a21f1c0f1
Options: 13

d463d996-78cc-428e-8a76-e4875e1c8ff4
RescheudleApt : 3
ConfirmApt: 2

Так как это кортеж, элементы разделяются на «Item 1» и «Item 2», что означает, что 60b0e926-2f3a-458d-91f7-fe4a21f1c0f1 и Options ,Options ,Options ,Options ,Options ,Options ,Options ,Options ,Options ,Options ,Options ,Options ,Options - это разные свойства.

Я дошел до этого:

        foreach (var item in intents)
        {
            var intentList = item.Item2.Split(',')
                .Select(x => x.Trim())
                .Where(x => !string.IsNullOrWhiteSpace(x))
                .ToList().GroupBy(x => x)
                .Select(g => new { Value = g.Key, Count = g.Count() })
                .OrderByDescending(x => x.Count);
        }

Что дает мне вывод двух свойств:

Value : Options
Count : 13

EDIT: Содержание является List<Tuple<string, string>>()

Как бы я поступил так?

Ответы [ 2 ]

4 голосов
/ 18 июня 2019
intents.Select(root => new 
{ 
    Key = root.Item1, 
    Values = root.Item2.Split(',')
        .Select(x => x.Trim())
        .Where(x => !string.IsNullOrWhiteSpace(x))
        .GroupBy(x => x)
        .Select(g => new 
        { 
            Value = g.Key, 
            Count = g.Count() 
        })
        .OrderByDescending(x => x.Count)
})
.ToList()
.ForEach(x => 
{
    Console.WriteLine(x.Key);
    x.Values.ForEach(child => Console.WriteLine($"{child.Key}: {child.Value}"))
});
1 голос
/ 18 июня 2019

Другой способ сделать это - выбрать элементы в Dictionary<string, Dictionary<string, int>>, где Key - это Item1, а Value - это другой словарь , в котором есть уникальные элементы. Item2 для Keys, а Values - это счетчик каждого элемента вместо использования анонимных типов.

Обратите внимание, что вы можете добавить StringSplitOptions.RemoveEmptyEntries к методу Split, что позволяет убрать проверку для .Where(x => !string.IsNullOrWhiteSpace(x)), и нет необходимости вызывать .ToList() перед выполнением GroupBy.

Например:

Dictionary<string, Dictionary<string, int>> results = intents.ToDictionary(
    item => item.Item1,
    item => item.Item2.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries)
        .Select(x => x.Trim())
        .GroupBy(x => x)
        .ToDictionary(group => group.Key, group => group.Count()));

Теперь мы можем перебирать результаты следующим образом:

foreach (var item in results)
{
    Console.WriteLine(item.Key + Environment.NewLine +
        string.Join(Environment.NewLine, item.Value.Select(v => $" - {v.Key}: {v.Value}")) +
        Environment.NewLine);
}

И вывод выглядит так:

![enter image description here* * 1030

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...