如果我有以下列表
List<int> Values = new List<int>() { 1, 5, 6, 2, 5 };
我想检查重复项,因此我使用GroupBy:
Values.GroupBy(x => x).Where(g => g.Count() > 1).Select(g => g.Key)
如何在While条件/转换为布尔值中使这个工作,以便,当且仅当值中存在任何重复项时,评估为true,否则,使用Linq评估false?我怀疑我需要使用。不知何故,但我不知道在哪里适合它。
答案 0 :(得分:2)
在列表中添加随机生成的数字之前,只需检查
do
{
var randomNumber = //Generate number here
if(!Values.Contains(randomNumber))
{
Values.Add(randomNumber);
break;
}
}while(true);
答案 1 :(得分:1)
这里的根本问题是您正在使用选择呼叫。您正在使用的Select调用将返回IEnumerable of longs,而不是布尔值。
这样的代码只能编译为布尔值的一部分(无论是作为bool变量还是作为在If,While等中完成的检查),如果同时删除Select和Where调用,以及用Any:
替换它List<int> Values = new List<int>() { 1, 5, 6, 2, 5 };
Values.GroupBy(x => x).Any(g => g.Count() > 1);
如果你需要找出重复项实际上是什么,那么最好的方法是将Group调用的结果存储在一个变量中,然后使用该变量在你的布尔检查中调用Any,当你想要报告它们时,从变量中获取项目:
List<int> Values = new List<int>() { 1, 5, 6, 2, 5 };
var duplicateValues = Values.GroupBy(x => x).Where(g => g.Count() > 1);
bool anyDuplicates = duplicateValues.Any();
var duplicateKeys = duplicateValues.Select(x => x.Key).ToList();
答案 2 :(得分:0)
您可以使用foreach
循环的组合和HashSet<int>.Add
方法的返回值
使用这种方法,如果早期发现重复,则不需要循环所有值。 GroupBy
应始终循环所有值。
public static bool HaveDuplicates(this IEnumerable<int> values)
{
var set = new HashSet<int>();
foreach (var value in values)
{
if (set.Add(value) == false)
{
return true;
}
}
return false;
}
将其用作扩展方法
var values = new List<int>() { 1, 5, 6, 1, 2, 5, 6, 7, 8, 9 };
if (values.HaveDuplicates())
{
// have duplicates
}
我试图在do while循环中使用它。在里面,我生成一个 从1到9的随机数,并将其添加到值列表中。如果 生成的数字是已经在列表中的数字,然后运行 再次循环。如果没有,请退出循环
使用HashSet<T>
保存生成的号码。 HashSet<T>
将检查与O(1)操作的重复,其中
var values = new HashSet<int>();
do
{
var generatedValue = GenerateNumber(); // your generation logic
if(values.Add(generatedValue) == false)
{
break;
}
}
while(yourCondition);
您可以将HashSet作为其他集合循环,或者如果需要,可以将其转换为List
var numbers = values.ToList();