Использование LINQ для группировки списка строк на основе известных подстрок, которые они будут содержать - PullRequest
1 голос
/ 28 июля 2011

У меня есть известный список строк вроде следующего:

List<string> groupNames = new List<string>(){"Group1","Group2","Group3"};

У меня также есть список неизвестных заранее строк, который будет выглядеть примерно так:

List<string> dataList = new List<string>()
{
   "Group1.SomeOtherText",
   "Group1.SomeOtherText2",
   "Group3.MoreText",
   "Group2.EvenMoreText"
};

Я хочу сделать оператор LINQ, который возьмет dataList и преобразует его либо в анонимный объект, либо в словарь с ключом имени группы и значением, содержащим список строк в этой группе. С целью зацикливания групп и внутреннего зацикливания над списком групп и выполнения различных действий со строками в зависимости от того, в какую группу он входит.

Мне бы хотелось, чтобы структура данных выглядела примерно так:

var grouped = new
{
   new
   {
       Key="Group1",
       DataList=new List<string>()
            {
               "Group1.SomeOtherText",
               "Group1.SomeOtherText2"
            }
    },
    new 
    {
       Key="Group2",
       DataList=new List<string>()
            {
               "Group2.EvenMoreText"
            }
    }
    ...
};

Я знаю, что могу просто пройтись по списку данных, а затем проверить, содержит ли каждая строка имя группы, и добавить их в отдельные списки, но я пытаюсь изучить способ выполнения такой задачи с помощью LINQ.

Заранее спасибо.

EDIT:

Просто пришла другая идея ... Что если имена моей группы были в Enum?

public enum Groups
{
    Group1,
    Group2,
    Group3
}

Как я могу получить это в словаре>?

Это то, что я пытаюсь, но я не уверен, как сформировать часть ToDictionary

Dictionary<Groups,List<string>> groupedDictionary =   (from groupName in Enum.GetNames(typeof(Groups))
                                                      from data in dataList 
                                                      where data.Contains(groupName)
                                                      group data by groupName).ToDictionary<Groups,List<string>>(...NOT SURE WHAT TO PUT HERE....);

РЕДАКТИРОВАТЬ 2:

Нашел решение вопроса Enum:

var enumType = typeof(Groups);
Dictionary<Groups,List<string>> query = (from groupName in Enum.GetValues(enumType).Cast<Groups>()
             from data in dataList
             where data.Contains(Enum.GetName(enumType, groupName))
             group data by groupName).ToDictionary(x => x.Key, x=> x.ToList());

1 Ответ

4 голосов
/ 28 июля 2011

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

var query = from groupName in groupNames
            from data in dataList
            where data.StartsWith(groupName)
            group data by groupName;

Обратите внимание, что это не является объединением, так как потенциально существуют перекрывающиеся имена групп "G" и "Gr", например, поэтому элемент может совпадать с несколькими именами групп. Если бы вы могли извлечь имя группы из каждого элемента (например, взяв все до первой точки), вы могли бы использовать «join ... into», чтобы получить групповое соединение. Так или иначе ...

Тогда:

foreach (var result in query)
{
    Console.WriteLine("Key: {0}", result.Key);
    foreach (var item in result)
    {
        Console.WriteLine("  " + item);
    }
}

Если вам действительно нужен анонимный тип, вы можете сделать ...

var query = from groupName in groupNames
            from data in dataList
            where data.StartsWith(groupName)
            group data by groupName into g
            select new { g.Key, DataList = g.ToList() };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...