Это та задача, для которой LINQ хорошо подходит.
Сначала давайте определим, что мы делаем:
- Группировка товаров по значению
- Подсчитайте каждую группу
- Вернуть предмет, группа которого имеет наибольшее количество
Этот запрос реализует вышеуказанное:
private string GetMostFrequent(IEnumerable<string> items)
{
var itemsOrderedByCount =
from item in items
group item by item into itemGroup
orderby itemGroup.Count() descending, itemGroup.Key
select itemGroup.Key;
return itemsOrderedByCount.FirstOrDefault();
}
Реализация очень похожа на высокоуровневое описание, приятный побочный эффект декларативного синтаксиса. Вот краткое объяснение каждой части:
from item in items
похоже на объявление цикла; item
относится к переменной цикла.
group item by item into itemGroup
Это помещает каждый item
в группу на основе его значения.
orderby itemGroup.Count() descending, itemGroup.Key
Это подсчитывает каждую группу и сортирует их так, что наиболее часто встречается первое. Если есть две группы с одинаковым количеством, выбирается меньшее значение. (Поскольку каждая группа содержит все одинаковые значения, ключ - это подсчитанный элемент.)
select itemGroup.Key
Это говорит о том, что для каждой группы мы просто хотим подсчитать элемент.
return itemsOrderedByCount.FirstOrDefault();
Это захватывает первый элемент в упорядоченном списке (тот, который имеет наибольшее количество). Если исходная последовательность пуста, возвращается ноль.
Использование:
var items = new[] { "BOB", "JOHN", "TOM", "TOM", "TOM" };
Assert.AreEqual("TOM", GetMostFrequent(items));