从第一次出现的集合中删除重复项目

时间:2011-11-11 11:08:55

标签: c# .net collections

我有一个类型字符串集合,可以包含任意数量的元素。

现在我需要找出所有那些重复的元素,只找出重复元素的第一次出现并删除其余部分。

前者

 public class CollectionCategoryTitle
    {
        public long CollectionTitleId { get; set; }
        public bool CollectionTitleIdSpecified { get; set; }
        public string SortOrder { get; set; }
        public TitlePerformance performanceField { get; set; }      
        public string NewOrder { get; set; }    
    }

    List<CollectionCategoryTitle> reorderTitles = 
        (List<CollectionCategoryTitle>)json_serializer
            .Deserialize<List<CollectionCategoryTitle>>(rTitles);

现在我需要以这样的方式处理这个集合,它会删除重复但它必须保持第一次出现。

编辑:

我已经更新了代码,我需要比较“NewOrder”属性

由于

3 个答案:

答案 0 :(得分:6)

针对您的具体情况:

var withoutDuplicates = reorderTitles.GroupBy(z => z.NewOrder).Select(z => z.First()).ToList();

对于更一般的情况,通常优选Distinct()。例如:

        List<int> a = new List<int>();
        a.Add(4);
        a.Add(1);
        a.Add(2);
        a.Add(2);
        a.Add(4);

        a = a.Distinct().ToList();

将返回4,1,2。请注意,Distinct不保证返回数据的顺序(当前实现似乎确实根据原始数据的顺序返回它们 - 但这是undocumented因此不应该依赖。)

答案 1 :(得分:3)

使用Enumerable.Distinct<T>()扩展名方法执行此操作。

答案 2 :(得分:2)

编辑:mjwills正确地指出保证排序在问题中很重要,因此其他两个建议不能保证工作。只留下提供这种保证的那个。

private static IEnumerable<CollectionCategoryTitle> DistinctNewOrder(IEnumerable<CollectionCategoryTitle> src)
{
  HashSet<string> seen = new HashSet<string>();
  //for one last time, change for different string comparisons, such as
  //new HashSet<string>(StringComparer.CurrentCultureIgnoreCase)
  foreach(var item in src)
    if(seen.Add(item.NewOrder))
      yield return item;
}
/*...*/
var distinctTitles = reorderTitles.DistinctNewOrder().ToList();

最后,如果您确实需要将.ToList()作为列表,请仅在DistinctNewOrder()之后使用{{1}}。如果您要处理结果一次然后不再进一步工作,那么最好不要创建浪费时间和内存的列表。