группировка объектов linq - PullRequest
4 голосов
/ 10 мая 2011

У меня есть объект people, а у poeple есть группа свойств, которая делает их принадлежащими к разным группам.Я хочу получить List и поместить его в объект GrouppedPeople, в котором будет List coll.Один элемент coll содержит только людей, принадлежащих к одной группе.

Так что, если бы у меня было 3 человека:

List<People>(){new People{Name="Test", Group = "Group1"},
               new People{Name="SameGroup", Group = "Group1"},
               new People{Name="Other", Group = "OtherGroup"}}

, мне нужно иметь коллекцию из 2 GrouppedPeople.Первый будет содержать Test и SameGroup, а второй будет содержать Other (сгруппированный по свойству Group).Я пытаюсь сделать это с помощью linq.

Мне нужно, чтобы результаты были типа List.GrouppedPeople - это класс, который имеет только одно свойство типа List, и все люди принадлежат к одной группе.

Я получил нечто подобное:

from oneGroup in mates
                   group oneGroup by oneGroup.pGroupName into g
                   select g;

Работает нормально, ноОбъект результата не является строго типизированным.И я хотел бы иметь список в качестве результата.Есть ли способ получить его от этого анонимного типа объекта?Есть ли другие способы получить все это с помощью linq и постоянно печатать?

Ответы [ 3 ]

4 голосов
/ 10 мая 2011

Это вернет список объектов анонимного типа:

var result = (from oneGroup in mates
                   group oneGroup by oneGroup.pGroupName into g
                   select g).ToList();

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

public class MateGroup
{
 public string Name {get;set;}
}

var result = (from oneGroup in mates
                   group oneGroup by oneGroup.pGroupName into g
                   select new MateGroup(){ Name =  g.<field_name>}).ToList();

UPD:

Согласно вашему комментарию, пожалуйста, попробуйте следующее:

var result = (from oneGroup in mates
                   group oneGroup by oneGroup.pGroupName into g
                   select new GrouppedPeople(){ People =  g.ToList()}).ToList();
3 голосов
/ 10 мая 2011

То, что вы получите, это IEnumerable<IGrouping<string, People>>. Интерфейс IGrouping<TKey, TElement> содержит Key, содержащий значение, по которому вы сгруппированы (в вашем случае строка, содержащая значение из свойства Group в объекте People ), и вы можете перечислить его, чтобы получить элементы, принадлежащие к группе:

IEnumerable<IGrouping<string, People>> result = from oneGroup in mates
                group oneGroup by oneGroup.Group into g
                select g;

foreach (IGrouping<string, People> grouping in result)
{
    Console.WriteLine("Group: {0}", grouping.Key);
    foreach (People people in grouping)
    {
        Console.WriteLine(" - {0}", people.Name);
    }
}

Результирующий вывод (на основе ваших данных выборки):

Group: Group1
 - Test
 - SameGroup
Group: OtherGroup
 - Other
2 голосов
/ 10 мая 2011

Я предпочитаю общий синтаксис C # для написания LINQ-запроса, который более понятен, чем простая форма запроса.

Вы можете использовать селектор результатов, чтобы разрешить результат группировки как типизированный объект.Полный код приложения консоли тестирования:

class People
{
    public string Name;
    public string Group;
}

class GroupedPeople
{
    public string Group;
    public List<People> People;
}

class Program
{
    static void Main(string[] args)
    {
        var mates = new List<People>()
        {
            new People{Name="Test", Group = "Group1"},
            new People{Name="SameGroup", Group = "Group1"},
            new People{Name="Other", Group = "OtherGroup"}
        };

        var resultList = mates
            .GroupBy(p => p.Group, (g, p) => new GroupedPeople() { Group = g, People = p.ToList() })
            .ToList();
    }
}

Для вызова GroupBy требуются два аргумента:

  1. p => p.Group - лямбда (анонимный метод), используемый для возврата ключа группировки

  2. (g, p) => new GroupedPeople() { Group = g, People = p.ToList() }

    Эта лямбда использовалась для создания объекта GroupedPeople на основе параметров группы, первый аргумент - это ключ группировки, выбранный первой лямбда, второй аргумент - перечисление сэлементы, относящиеся к текущей группе.

...