检查数组是否有重复项,仅返回出现多次的项目

And*_*ndy 1 c# arrays string text duplicates

我有一个电子邮件的文本文件,如

Google12@gmail.com,
MyUSERNAME@me.com,
ME@you.com,
ratonabat@co.co,
iamcool@asd.com,
ratonabat@co.co,
Run Code Online (Sandbox Code Playgroud)

我需要检查所述文件是否有重复项并从中创建一个独特的数组(因此如果"ratonabat@co.co"在新数组中出现500次,他只会出现一次.)

编辑:举个例子:

username1@hotmail.com
username2@hotmail.com
username1@hotmail.com
username1@hotmail.com
username1@hotmail.com
username1@hotmail.com
Run Code Online (Sandbox Code Playgroud)

这是我的"数据"(在数组或文本文档中,我可以处理)

我希望能够看到它是否有重复,并将重复的ONCE移动到另一个数组.所以输出就是

username1@hotmail.com
Run Code Online (Sandbox Code Playgroud)

p.s*_*w.g 10

您可以简单地使用Linq的Distinct扩展方法:

var input = new string[] { ... };
var output = input.Distinct().ToArray();
Run Code Online (Sandbox Code Playgroud)

您可能还需要考虑重构代码以使用HashSet<string>而不是简单的数组,因为它将优雅地处理重复项.


要获得一个只包含那些重复记录的数组,它有点复杂,但你仍然可以使用一点Linq:

var output = input.GroupBy(x => x)
                  .Where(g => g.Skip(1).Any())
                  .Select(g => g.Key)
                  .ToArray();
Run Code Online (Sandbox Code Playgroud)

说明:

  • .GroupBy 将相同的字符串组合
  • .Where 按以下标准过滤组
    • .Skip(1).Any()如果组中有2个或更多项,则返回true.这相当于.Count() > 1,但效率稍高,因为它在找到第二个项目后停止计数.
  • .Select 返回仅包含单个字符串(而不是组)的集合
  • .ToArray 将结果集转换为数组.

这是使用自定义扩展方法的另一种解决方案:

public static class MyExtensions
{
    public static IEnumerable<T> Duplicates<T>(this IEnumerable<T> input)
    {
        var a = new HashSet<T>();
        var b = new HashSet<T>();
        foreach(var x in input)
        {
            if (!a.Add(x) && b.Add(x))
                yield return x;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样调用这个方法:

var output = input.Duplicates().ToArray();
Run Code Online (Sandbox Code Playgroud)

我没有对此进行基准测试,但它应该比以前的方法更有效.