该表达式在GroupBy方法中意味着什么?

时间:2018-08-03 02:30:00

标签: c# linq

bool test = anyCollection.GroupBy(x => "AnyKeyString").Any(g => g.Count() > 1);

此Lambda始终返回true,在这里我认为它的意思是“将占位符x设为true(因为字符串本身始终为true ??),并按集合中所有为true的东西分组” < / p>

我的问题是为什么我在GroupBy中放一个字符串总是返回true?

我不太确定,当我在集合中找到重复的值时,我受到启发,下面是示例:

    public class Alphabet
    {
      public int ID { get; set; }
      public string Initial { get; set; }
    }

        List<Alphabet> testList = new List<Alphabet>()
        {
            new Alphabet() { ID = 1, Initial = "A"},
            new Alphabet() { ID = 2, Initial = "B"},
            new Alphabet() { ID = 3, Initial = "C"},
            new Alphabet() { ID = 4, Initial = "D"},
        };

        List<Alphabet> testList2 = new List<Alphabet>()
        {
            new Alphabet() { ID = 1, Initial = "A"},
            new Alphabet() { ID = 2, Initial = "A"},
            new Alphabet() { ID = 3, Initial = "C"},
            new Alphabet() { ID = 4, Initial = "C"},
        };

        bool test1 = testList.GroupBy(x => x.Initial).Any(g => g.Count() > 1);
        // false
        bool test2 = testList2.GroupBy(x => x.Initial).Any(g => g.Count() > 1);
        // true
        bool test3 = testList2.GroupBy(x => "Initial").Any(g => g.Count() > 1);
        // true

有点题外话,我如何按通用类型列表分组?

    List<string> testList = new List<string>(){
        "A",
        "B",
        "C",
        "D"
    };

    List<string> testList2 = new List<string>(){
        "A",
        "A",
        "C",
        "D"
    };

    var k = testList.GroupBy(x => ????).Any(g => g.Count() > 1);
    var c = testList2.GroupBy(x => "A").Any(g => g.Count() > 1);
    // always true

1 个答案:

答案 0 :(得分:1)

.GroupBy不是过滤器-不是.Where.GroupBy使用键选择器Func<TObject, TKey>

因此,如果您具有这样的函数(相当于x => x.Initial):

public string GetGroupKeyForObject(Alphabet alpha)
{
    return alpha.Initial;
}

可以通过以下方式传递:.GroupBy(GetGroupKeyForObject)

然后它将按首字母分组。但是,如果您具有类似这样的功能(相当于x => "anystring"):

public string GetGroupKeyForObject(Alphabet alpha)
{
    return "anystring";
}

然后所有项目将被确定具有键“ anystring”以进行分组。

如果您只想选择以“ anystring”开头的项目,则应该这样做:

bool result = testList.Where(a => a.Initial == "anystring").Count() > 1;

或效率更高(但可读性较低):

bool result = testList.Where(a => a.Initial == "anystring").Skip(1).Any();

想象一下您有这个测试集:

字母(为简洁起见,仅显示首字母缩写,但与您的字母相同):["A", "A","B", "B", "B", "B","C","D","E","F"]

然后按Initial将其分组,您将获得6组:

键:组项目

A:["A", "A"]

B:["B", "B", "B", "B"]

C:["C"]

D:["D"]

E:["E"]

F:["F"]

但是,如果按“ anystring”将其分组,则会得到1组:

键:组项目

任何字符串:["A", "A","B", "B", "B", "B","C","D","E","F"]

因此,在第一个示例上执行.Any(x => x.Count() > 1)将返回true,因为A和B的计数都大于1。 在第二个示例中执行相同的操作与在原始集合上调用.Count() > 1相同,因为您要按静态值对整个选择进行分组,所以只能得到一组。