-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 回答
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);

这将为您提供排序集

于 2013-07-24T08:08:58.883 回答
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());
于 2013-07-24T08:43:06.940 回答
1

您可以对列表进行排序,然后删除所有重复的项目,但似乎将所有数据存储在 aDictionary<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;
        }
    }
}

其次是在您的项目中使用.Distinct()和覆盖Equals以匹配名称

于 2013-07-24T08:04:34.673 回答