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 () не