これは、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
これにより、各グループがカウントされ、最も頻度の高いものが最初になるように並べ替えられます。カウントが同じグループが 2 つある場合は、小さい方の値が選択されます。(各グループにはすべて同じ値が含まれているため、キーはカウントされたアイテムです。)
select itemGroup.Key
これは、各グループについて、カウントされたアイテムだけが必要であることを示しています。
return itemsOrderedByCount.FirstOrDefault();
これにより、順序付けられたリストの最初の項目 (カウントが最も高い項目) が取得されます。元のシーケンスが空の場合、null が返されます。
使用法:
var items = new[] { "BOB", "JOHN", "TOM", "TOM", "TOM" };
Assert.AreEqual("TOM", GetMostFrequent(items));