GroupBy
і ToLookUp
має майже таку ж функціональність КРІМ це: Посилання
GroupBy: Оператор GroupBy повертає групи елементів на основі деякого значення ключа. Кожна група представлена об'єктом IGrouping.
ToLookup: ToLookup те саме, що і GroupBy; єдина відмінність - виконання GroupBy відкладено, тоді як виконання ToLookup відбувається негайно.
Давайте очистимо різницю, використовуючи зразок коду припустимо, що у нас є клас, що представляє Person
модель:
class Personnel
{
public int Id { get; set; }
public string FullName { get; set; }
public int Level { get; set; }
}
після цього ми визначаємо список, personnels
як показано нижче:
var personnels = new List<Personnel>
{
new Personnel { Id = 1, FullName = "P1", Level = 1 },
new Personnel { Id = 2, FullName = "P2", Level = 2 },
new Personnel { Id = 3, FullName = "P3", Level = 1 },
new Personnel { Id = 4, FullName = "P4", Level = 1 },
new Personnel { Id = 5, FullName = "P5", Level =2 },
new Personnel { Id = 6, FullName = "P6", Level = 2 },
new Personnel { Id = 7, FullName = "P7", Level = 2 }
};
Тепер мені потрібно отримати personnels
згруповані за їх рівнем. У мене тут два підходи. використовуючи GroupBy
або ToLookUp
. Якщо я використовую GroupBy
, як зазначено раніше, він буде використовувати відкладене виконання, це означає, що коли ви переглядаєте колекцію, наступний елемент може обчислюватися, а може і не обчислюватися, доки його не буде викликано.
var groups = personnels.GroupBy(p => p.Level);
personnels.RemoveAll(p => p.Level == 1);
foreach (var product in groups)
{
Console.WriteLine(product.Key);
foreach (var item in product)
Console.WriteLine(item.Id + " >>> " + item.FullName + " >>> " + item.Level);
}
У наведеному вище коді я спочатку згрупував файл personnels
, але перед його повторенням видалив деякі personnels
. Оскільки GroupBy
використовується відкладене виконання, тому кінцевий результат не включатиме вилучені елементи, оскільки групування буде обчислюватися в foreach
точці тут.
Вихід:
2
2 >>> P2 >>> 2
5 >>> P5 >>> 2
6 >>> P6 >>> 2
7 >>> P7 >>> 2
Але якщо я перепишу наведений вище код, як показано нижче: (зверніть увагу, що код такий самий, як і попередній код, за винятком того GroupBy
, що замінюється на ToLookUp
)
var groups = personnels.ToLookup(p => p.Level);
personnels.RemoveAll(p => p.Level == 1);
foreach (var product in groups)
{
Console.WriteLine(product.Key);
foreach (var item in product)
Console.WriteLine(item.Id + " >>> " + item.FullName + " >>> " + item.Level);
}
Оскільки ToLookUp
використовується негайне виконання, це означає, що коли я викликаю ToLookUp
метод, генерується результат і застосовується група, тому, якщо я вилучу будь-який елемент personnels
до ітерації, це не вплине на кінцевий результат.
Вихід:
1
1 >>> P1 >>> 1
3 >>> P3 >>> 1
4 >>> P4 >>> 1
2
2 >>> P2 >>> 2
5 >>> P5 >>> 2
6 >>> P6 >>> 2
7 >>> P7 >>> 2
Примітка: GroupBy
і ToLookUp
обидва також повертають різні типи.
Ви можете використовувати ToDictionary замість ToLookUp, але вам потрібно звернути увагу на це :( посилання )
Використання ToLookup () дуже схоже на використання ToDictionary (), обидва дозволяють вказати селектори ключів, селектори значень та порівняльники. Основна відмінність полягає в тому, що ToLookup () дозволяє (і очікує) дублікатів ключів, тоді як ToDictionary () не