假设我有一个字符串列表,如下所示:
var candidates = new List<String> { "Peter", "Chris", "Maggie", "Virginia" };
现在,我想验证另一个List<String>
,让我们称之为list1
,只包含每个候选人一次。
我怎么能这样做,简单?我想我可以使用Intersect()
。我也希望找到失踪的候选人。
private bool ContainsAllCandidatesOnce(List<String> list1)
{
????
}
private IEnumerable<String> MissingCandidates(List<String> list1)
{
????
}
订单无关紧要。
答案 0 :(得分:5)
这在速度方面可能不是最优的,但两个查询都足够短,可以放在一行,并且易于理解:
private bool ContainsAllCandidatesOnce(List<String> list1)
{
return candidates.All(c => list1.Count(v => v == c) == 1);
}
private IEnumerable<String> MissingCandidates(List<String> list1)
{
return candidates.Where(c => list1.Count(v => v == c) != 1);
}
答案 1 :(得分:2)
我们在此谈论Except,Intersect和Distinct。我可以使用带表达式的lamba运算符,但它必须遍历每个项目。该功能可用于预定义的功能。
第一种方法
var candidates = new List<String> { "Peter", "Chris", "Maggie", "Virginia" };
private bool ContainsAllCandidatesOnce(List<String> list1)
{
list1.Intersect(candidates).Distinct().Any();
}
这将给list1中的任何元素在候选列表中是常见的,或者你可以用其他方式执行
candidates.Intersect(list1).Distinct().Any();
第二种方法
private IEnumerable<String> MissingCandidates(List<String> list1)
{
list1.Except(candidates).AsEnumerable();
}
这将删除list1中候选人中的所有元素。如果您想以其他方式做到这一点
candidates.Except(list1).AsEnumerable();
答案 2 :(得分:1)
这应该非常有效:
IEnumerable<string> strings = ...
var uniqueStrings = from str in strings
group str by str into g
where g.Count() == 1
select g.Key;
var missingCandidates = candidates.Except(uniqueStrings).ToList();
bool isValid = !missingCandidates.Any();
答案 3 :(得分:1)
GroupJoin是这项工作的正确工具。来自msdn:
GroupJoin生成分层结果,表示元素 从外部与匹配元素的集合配对 内。 GroupJoin使您可以将结果基于一整套 匹配外部的每个元素。
如果外部的给定元素的内部没有相关元素,则该元素的匹配序列将为空 仍然会出现在结果中。
因此,对于源中的每个项目,GroupJoin将找到目标的任何匹配项。如果在目标中找不到匹配项,则不会过滤源中的项目。相反,他们匹配一个空组。
Dictionary<string, int> counts = candidates
.GroupJoin(
list1,
c => c,
s => s,
(c, g) => new { Key = c, Count = g.Count()
)
.ToDictionary(x => x.Key, x => x.Count);
List<string> missing = counts.Keys
.Where(key => counts[key] == 0)
.ToList();
List<string> tooMany = counts.Keys
.Where(key => 1 < counts[key])
.ToList();
答案 4 :(得分:0)
private bool ContainsAllCandidatesOnce(List<String> list1)
{
return list1.Where(s => candidates.Contains(s)).Count() == candidates.Count();
}
private IEnumerable<String> MissingCandidates(List<String> list1)
{
return candidates.Where(s => list1.Count(c => c == s) != 1);
}
答案 5 :(得分:0)
如何使用HashSet而不是List?
答案 6 :(得分:-1)
private static bool ContainsAllCandidatesOnce(List<string> lotsOfCandidates)
{
foreach (string candidate in allCandidates)
{
if (lotsOfCandidates.Count(t => t.Equals(candidate)) != 1)
{
return false;
}
}
return true;
}
private static IEnumerable<string> MissingCandidates(List<string> lotsOfCandidates)
{
List<string> missingCandidates = new List<string>();
foreach (string candidate in allCandidates)
{
if (lotsOfCandidates.Count(t => t.Equals(candidate)) != 1)
{
missingCandidates.Add(candidate);
}
}
return missingCandidates;
}