Linq GroupBy转换为有条件的?

时间:2017-10-23 05:26:15

标签: c# linq

如果我有以下列表

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?我怀疑我需要使用。不知何故,但我不知道在哪里适合它。

3 个答案:

答案 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();