-2

次のコレクションがあり、500000 を超えるアイテムがあります。

List<Item> MyCollection = new List<Item>();

次のように入力します。

class Item
{
   public string Name { get; set; }
   public string Description { get; set; }
}

個別の名前を持つアイテムのリストを返したいです。つまり、名前に基づいて個別のアイテムを見つけます。

考えられる方法は何ですか?時間とメモリの点で最適なのはどれですか? どちらも重要ですが、メモリよりも時間が少ない方が優先されます。

4

6 に答える 6

4

パフォーマンスが不十分でない限り、またはパフォーマンスが不十分であることが判明するまで、Linqを選択します。

var considered = from i in MyCollection
         group i by i.Name into g
         select new { Name = g.Key, Cnt = g.Count(), Instance = g.First() };
var result = from c in considered where c.Cnt == 1 select c.Instance;

Name(あなたの質問を「リストに一度だけ表示されるアイテムを返す」と正しく解釈したと仮定します)

于 2013-07-24T08:04:48.690 に答える
1

リストを並べ替えてから、繰り返されるすべてのアイテムを削除できますがDictionary<string, string>、このタスクにはすべてのデータを に保存する方がよいようです。または、すべてのリストをHashSet.

于 2013-07-24T08:01:12.267 に答える
1

MoreLinqには、DistinctByこの種の作業に最適な拡張機能があり、オープン ソースであり、数行のコードしかないため、コードに簡単に追加できます。

var results = MyCollection.DistinctBy(p => p.Name);
于 2013-07-24T08:05:02.110 に答える
0

最初の解決策:

public static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> sequence, Func<T, TKey> keySelector)
{
    var alreadyUsed = new HashSet<TKey>();            
    foreach (var item in sequence)
    {
        var key = keySelector(item);
        if (alreadyUsed.Add(key))
        {
            yield return item;
        }
    }
}

2つ目は、名前と一致するようにアイテムを使用.Distinct()してオーバーライドすることですEquals

于 2013-07-24T08:04:34.673 に答える