【问题标题】:C# Get non duplicates in a list [duplicate]C#获取列表中的非重复项[重复]
【发布时间】:2013-09-25 15:37:32
【问题描述】:

这样的列表:

int[] numbers = {1,2,2,3,3,4,4,5};

我可以使用 Distinct() 函数删除重复项,因此列表将显示为:1,2,3,4,5

但是,我想要相反的。我希望它删除所有重复的数字,留下唯一的数字。

因此列表将显示为:1,5。

如何做到这一点?

【问题讨论】:

    标签: c#


    【解决方案1】:

    值得一提的是,一个检查序列是否包含超过 N 元素的扩展:

    public static bool CountMoreThan<TSource>(this IEnumerable<TSource> source, int num)
    {
        if (source == null)
            throw new ArgumentNullException("source");
        if (num < 0)
            throw new ArgumentException("num must be greater or equal 0", "num");
    
        ICollection<TSource> collection = source as ICollection<TSource>;
        if (collection != null)
        {
            return collection.Count > num;
        }
        ICollection collection2 = source as ICollection;
        if (collection2 != null)
        {
            return collection2.Count > num;
        }
    
        int count = 0;
        using (IEnumerator<TSource> enumerator = source.GetEnumerator())
        {
            while (++count <= num + 1)
                if (!enumerator.MoveNext())
                    return false;
        }
        return true;
    }
    

    现在变得简单高效:

    var allUniques = numbers.GroupBy(i => i)
        .Where(group => !group.CountMoreThan(1))
        .Select(group => group.Key).ToList();
    

    DEMO

    或者,正如@KingKing 对乔恩的回答所评论的那样:

    var allUniques = numbers.GroupBy(i => i)
        .Where(group => !group.Skip(1).Any())
        .Select(group => group.Key).ToList();
    

    【讨论】:

    • 加一个,用于使用.Skip(1).Any() 而不是.Count() &gt; 1
    【解决方案2】:

    一种方法是

    var singles = numbers.GroupBy(n => n)
                         .Where(g => g.Count() == 1)
                         .Select(g => g.Key); // add .ToArray() etc as required
    

    【讨论】:

    • !g.Skip(1).Any() 在我看来会比g.Count()==1稍微好一点。
    • @KingKing:我相信组实现包含缓存的项目数,所以.Count() 是最好的。我认为我曾在某个时候对此进行过基准测试,但我现在找不到它,所以我只有 99% 的把握。
    • @KingKing:在我的回答中借用了您的评论 :) 在 Jon:不,GroupBy 正在使用延迟执行,但 Count() 将完全执行它。
    • 很高兴知道这一点,我认为它必须再次遍历每个组中的所有元素才能获得Count。感谢您的回复。
    • @KingKing:我确实找到了。 Here's the code;使用它可以清楚地表明.Count() 在这种情况下是恒定的时间。
    【解决方案3】:
    var cleanArray = numbers.GroupBy(x=>x)
      .Where(x=>x.Count() == 1)
      .SelectMany(x=>x)
      .ToArray();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 2022-11-30
      • 2015-11-19
      • 1970-01-01
      • 1970-01-01
      • 2015-05-12
      • 1970-01-01
      相关资源
      最近更新 更多