我有一个以下的集合,它有超过500000个项目。
List<Item> MyCollection = new List<Item>();
并输入:
class Item
{
public string Name { get; set; }
public string Description { get; set; }
}
我想返回具有不同名称的项目列表。即根据名称找出不同的项目。
有什么可能的方法和这在时间和方面都是最好的记忆。虽然两者都很重要,但是时间比记忆更重要。
答案 0 :(得分: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
仅在列表中出现一次的项目”)
答案 1 :(得分: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);
这将为您提供有序集
答案 2 :(得分:1)
您可以对列表进行排序,然后删除所有重复的项目,但似乎将所有数据存储在Dictionary<string, string>
中对于此任务更好。或者甚至可以将所有列表放在HashSet
。
答案 3 :(得分:1)
MoreLinq有一个DistinctBy
扩展程序,非常适合这类内容,它的开源代码和几行代码很容易添加到代码中。
var results = MyCollection.DistinctBy(p => p.Name);
答案 4 :(得分: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());
答案 5 :(得分: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
以匹配名称