我有一份电子邮件的文本文件,例如
Google12@gmail.com,
MyUSERNAME@me.com,
ME@you.com,
ratonabat@co.co,
iamcool@asd.com,
ratonabat@co.co,
我需要检查所述文件是否有重复项并从中创建一个独特的数组(因此如果“ratonabat@co.co”在新数组中出现500次,他只会出现一次。)
编辑: 举个例子:
username1@hotmail.com
username2@hotmail.com
username1@hotmail.com
username1@hotmail.com
username1@hotmail.com
username1@hotmail.com
这是我的“数据”(在数组或文本文档中,我可以处理)
我希望能够看到它是否有重复,并将重复的ONCE移动到另一个数组。所以输出将是
username1@hotmail.com
答案 0 :(得分:10)
您可以简单地使用Linq的Distinct
扩展方法:
var input = new string[] { ... };
var output = input.Distinct().ToArray();
您可能还需要考虑重构代码以使用HashSet<string>
而不是简单数组,因为它会优雅地处理重复项。
要获得一个只包含那些重复记录的数组,它有点复杂,但你仍然可以用一点Linq来做:
var output = input.GroupBy(x => x)
.Where(g => g.Skip(1).Any())
.Select(g => g.Key)
.ToArray();
说明:
.GroupBy
将相同的字符串组合在一起.Where
按以下标准过滤组
.Skip(1).Any()
返回true。这相当于.Count() > 1
,但效率稍高,因为它在找到第二个项目后停止计数。.Select
返回仅包含单个字符串(而不是组)的集合.ToArray
将结果集转换为数组。以下是使用自定义extension method的另一种解决方案:
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;
}
}
}
然后你可以像这样调用这个方法:
var output = input.Duplicates().ToArray();
我没有对此进行基准测试,但它应该比以前的方法更有效。
答案 1 :(得分:3)
您可以使用.Distinct()
方法中的内置,默认情况下,比较区分大小写,如果您想使其区分大小写,请使用带有比较器的重载并使用不区分大小写的字符串比较器。 / p>
List<string> emailAddresses = GetListOfEmailAddresses();
string[] uniqueEmailAddresses = emailAddresses.Distinct(StringComparer.OrdinalIgnoreCase).ToArray();
编辑:现在,在您澄清之后,我看到您只想列出重复项。
string[] duplicateAddresses = emailAddresses.GroupBy(address => address,
(key, rows) => new {Key = key, Count = rows.Count()},
StringComparer.OrdinalIgnoreCase)
.Where(row => row.Count > 1)
.Select(row => row.Key)
.ToArray();
答案 2 :(得分:1)
选择多次出现的电子邮件..
var dupEmails=from emails in File.ReadAllText(path).Split(',').GroupBy(x=>x)
where emails.Count()>1
select emails.Key;