2013-07-24 135 views
-1

我有一個以下集合,它有超過500000個項目。查找大列表中不同項目的最佳方法

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

和類型:

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

我想回到具有不同名稱的項目清單。即根據名稱找出不同的項目。

什麼是&什麼是&內存最好。儘管兩者都很重要,但是更少的時間優先於內存。

+2

http://stackoverflow.com/a/5970996/1714342 – wudzik

+0

是否['Enumerable.Distinct()'](http://msdn.microsoft.com/en-us/library/system.linq .enumerable.distinct.aspx)不是做你想做的?或者你想要列表中只有列表中唯一的項目(與「Distinct()」不同)? –

+0

[更快的替代方法.Distinct()](http://stackoverflow.com/questions/5970983/faster-alternatives-to-distinct) –

回答

1

您可以對您的清單進行排序然後刪除所有重複的項目,但似乎將所有數據存儲在Dictionary<string, string>會更適合此任務。或者甚至可以把所有的列表放在HashSet

+0

不是我downvote,但字典類型不正確 –

+0

@lazyberezovsky爲什麼不是?類項目包含兩個字符串字段。 「名稱」可能是關鍵,「說明」是一個值,只適用於這種情況。 – Sergio

+0

實際上,存在不同項目的問題。因此,我認爲你有幾個同名的項目,適當的類型是'Dictionary >'(或Lookup)。但是如果答案解決了問題,那麼它當然是正確的+1 –

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; 
     } 
    } 
} 

二是使用.Distinct()並覆蓋Equals在您的項目相匹配的名字

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上ly出現在列表中的一次「)

+0

這就是我解釋這個問題的方式,但有點不清楚! –

1

MoreLinq有一個DistinctBy擴展,這對於這類事情來說很好,它的開源代碼和幾行代碼很容易添加到代碼中。

var results = MyCollection.DistinctBy(p => p.Name); 
2

我有代碼的Java版本

implement the comparator then define the method as below in Item class 

public int compare(MyObject o1, MyObject o2) 
{ 
    // return 0 if objects are equal in terms of your data members such as name or any 
} 

則於MyCollection的定義

HashSet<Item> set1 = new HashSet<Item>(); 
    set1.addAll(MyCollection); 
    MyCollection.clear(); 
    MyCollection.addAll(set1); 

類使用下面的代碼,這會給你的有序集合

1

我可以看到你找到了你的答案,但你也可以用Distinct;

internal class NameComparer : IEqualityComparer<Item> { 
    public bool Equals(Item x, Item y) { return x.Name == y.Name;  } 
    public int GetHashCode(Item obj) { return obj.Name.GetHashCode(); } 
} 

var distinctItems = MyCollection.Distinct(new NameComparer()); 
相關問題