Создать словарь в списке с группировкой - PullRequest
97 голосов
/ 02 июня 2009

У меня есть следующий объект в списке:

public class DemoClass
{
    public int GroupKey { get; set; }
    public string DemoString { get; set; }
    public object SomeOtherProperty { get; set; }
}

Теперь я хочу создать из него следующий словарь:

Dictionary<int, List<DemoClass>>

Я хочу сгруппировать List<DemoClass> по свойству GroupKey, но я не понимаю, как это делается и какая-то помощь.

Подумав немного, я достиг нужного поведения с помощью:

var groupedDemoClasses = from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                            group demoClass by demoClass.GroupKey
                            into groupedDemoClass
                            select groupedDemoClass;
var neededDictionary = groupedDemoClass.ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

но есть ли способ превратить это в одно утверждение?

Ответы [ 4 ]

186 голосов
/ 02 июня 2009

Просто чтобы сделать предложение Маквандера Бетон:

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .GroupBy(x => x.GroupKey)
                             .ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

Вы бы сделали его короче, если бы, конечно, тоже использовали более короткие имена переменных:)

Однако могу ли я предложить, что Lookup может быть более подходящим? Lookup - это, по сути, словарь от ключа к IEnumerable<T> - если вам действительно не нужно значения в виде списка, он делает код еще короче (и более эффективным) с помощью ToLookup Звоните:

var groupedDemoClasses = mySpecialVariableWhichIsAListOfDemoClass
                             .ToLookup(x => x.GroupKey);
80 голосов
/ 02 июня 2009
var groupedDemoClasses = (from demoClass in mySepcialVariableWhichIsAListOfDemoClass
                          group demoClass by demoClass.GroupKey
                          into groupedDemoClass
                          select groupedDemoClass).ToDictionary(gdc => gdc.Key, gdc => gdc.ToList());

Этот будет работать !!!

6 голосов
/ 02 июня 2009

Вы уже сделали это однострочником. Просто поставьте ToDictionary в конце вашей первой строки. Если вы хотите, чтобы он был короче, используйте синтаксис функциональной композиции вместо синтаксиса запроса.

3 голосов
/ 07 июля 2009

Я собираюсь немного не по теме здесь, но я попал в эту тему, потому что я искал способ создать словарь словаря в Linq, и разговор здесь привел меня к ответу ...

Вы можете использовать linq для создания многоуровневых словарей, что полезно для сценариев, в которых у вас есть более 1 ключа или измерения, по которым вы хотите выполнить поиск. Хитрость заключается в том, чтобы создать группировку и затем преобразовать ее в словарь следующим образом:

  Dim qry = (From acs In ActualSales _
             Group By acs.ProductID Into Group _
             Select ProductID, Months = Group.ToDictionary(Function(c) c.Period) _
            ).ToDictionary(Function(c) c.ProductID)

Полученный запрос можно использовать следующим образом:

 If qry.ContainsKey(_ProductID) Then
      With qry(_ProductID)
          If .Months.ContainsKey(_Period) Then
             ...
          End If
      End With
 End If

Надеюсь, что это полезно для всех, кому нужен такой запрос.

...