Давайте предположим, что у нас есть такой класс:
class Person {
internal int PersonID;
internal string car;
}
Теперь у меня есть список этого класса: List<Person> persons;
Теперь этот список может иметь несколько экземпляров с одинаковыми PersonID
, например:
persons[0] = new Person { PersonID = 1, car = "Ferrari" };
persons[1] = new Person { PersonID = 1, car = "BMW" };
persons[2] = new Person { PersonID = 2, car = "Audi" };
Есть ли способ, которым я могу сгруппироваться PersonID
и получить список всех автомобилей, которые у него есть?
Например, ожидаемый результат будет
class Result {
int PersonID;
List<string> cars;
}
Поэтому после группировки я получу:
results[0].PersonID = 1;
List<string> cars = results[0].cars;
result[1].PersonID = 2;
List<string> cars = result[1].cars;
Из того, что я сделал до сих пор:
var results = from p in persons
group p by p.PersonID into g
select new { PersonID = g.Key, // this is where I am not sure what to do
Может ли кто-нибудь, пожалуйста, указать мне в правильном направлении?
Count
иSum
здесь stackoverflow.com/questions/3414080/…Ответы:
Абсолютно - вы в основном хотите:
Или как выражение без запроса:
По существу, содержимое группы (если рассматривать ее как
IEnumerable<T>
) - это последовательность значений, которые были в проекции (p.car
в данном случае) для данного ключа.Подробнее о том
GroupBy
, как работает, смотрите мой пост Edulinq на эту тему .(Я переименовал
PersonID
вPersonId
в выше, чтобы следовать .NET соглашения о присвоении имен .)В качестве альтернативы вы можете использовать
Lookup
:Вы можете легко получить автомобили для каждого человека:
источник
.GroupBy(p => new {p.Id, p.Name}, p => p, (key, g) => new { PersonId = key.Id, PersonName = key.Name, PersonCount = g.Count()})
и вы получите всех людей, которые встречаются с идентификатором, именем и числом вхождений для каждого человека.источник
источник
Вы также можете попробовать это:
источник
пытаться
или
чтобы проверить, повторяется ли кто-либо в вашем списке, попробуйте
источник
Я создал пример рабочего кода с синтаксисом запроса и синтаксисом метода. Я надеюсь, что это помогает другим :)
Вы также можете запустить код на .Net Fiddle здесь:
Вот результат:
источник
Попробуй это :
Но с точки зрения производительности следующая практика лучше и более оптимизирована в использовании памяти (когда наш массив содержит гораздо больше элементов, таких как миллионы):
источник
g.Key.PersonId
?g.SelectMany
?? Вы явно не пробовали это.SortedDictionary <PersonIdInt, SortedDictionary <CarNameString, CarInfoClass>>
. Самое близкое, что я мог получить, используя LINQIEnumerable <IGrouping <PersonIdInt, Dictionary <CarNameString, PersonIdCarNameXrefClass>>>
. Я закончил, используя вашfor
метод цикла, который, кстати, был в 2 раза быстрее. Кроме того, я бы использовал: а)foreach
противfor
и б)TryGetValue
противContainsKey
(оба для принципа СУХОЙ - в коде и во время выполнения).Альтернативный способ сделать это может быть выбран отдельно
PersonId
и групповое объединение сpersons
:Или то же самое с беглым синтаксисом API:
GroupJoin создает список записей в первом списке (список
PersonId
в нашем случае), каждая из которых имеет группу соединенных записей во втором списке (списокpersons
).источник
В следующем примере метод GroupBy используется для возврата объектов, сгруппированных по
PersonID
.Или
Или
Или вы можете использовать
ToLookup
, в основномToLookup
используетEqualityComparer<TKey>
.Default для сравнения ключей и делать то, что вы должны делать вручную при использовании группировки по и словарю. я думаю, что это оправданоисточник
Сначала установите ключевое поле. Затем включите другие поля:
источник