有多少个Foos和Boos? (Linq,GroupBy)

时间:2017-07-10 14:10:16

标签: c# linq group-by

[EDIT1] 我希望使用LINQ获得“4 Foos,6 Boos”的结果。 [/编辑]

这对我来说是初级的,不是那么容易。

我写过像这样的经典代码。它将所有Foo视为Boo的重要性。

var myList = new List<string[]>();
myList.Add(new string[] { "Foo", "1" });
myList.Add(new string[] { "Boo", "2" });
myList.Add(new string[] { "Foo", "3" });
myList.Add(new string[] { "Boo", "4" });
var myDictionary = new Dictionary<string, int>();
foreach (var x in myList)
    if (myDictionary.ContainsKey(x[0]))
        myDictionary[x[0]] += int.Parse(x[1]);
    else
        myDictionary.Add(x[0], int.Parse(x[1]));
MessageBox.Show(string.Join("\n", 
    myDictionary.Select(x => x.Key +" : "+ x.Value)));

所以,我有4个Foos,6个Boos。

我没有学习,Linq。喜欢这个..

var myLinq = myList
    .OrderBy(x => x[0])
    .GroupBy(x => x[0])
    .Select(y => new
    {
        Key = y.Key,
        Value = y.Sum(x => x[1])
    });

请帮助..

3 个答案:

答案 0 :(得分:3)

var myLinq = from m in myList
         group m by m[0] into g
         select new
         {
            Key = g.Key,
            Value = g.Sum(gg=>int.Parse(gg[1]))
         };

答案 1 :(得分:1)

如评论中所述,您的第二个代码段正在尝试添加字符串,就好像它们是数字一样。这会产生编译错误,因为您必须先将字符串解析为整数,然后才能添加它们。

以下代码使用int.Parse将每个字符串解析为Sum()函数内的整数:

var myList = new List<string[]>{
    new string[] { "Foo", "1" },
    new string[] { "Boo", "2" },
    new string[] { "Foo", "3" },
    new string[] { "Boo", "4" },
};

var myLinq = myList
    .OrderBy(x => x[0])
    .GroupBy(x => x[0])
    .Select(y => new
    {
        Key = y.Key,
        Value = y.Sum(x => int.Parse(x[1]))
    });

注意,这是生成字符串和数字对的一种非常不寻常的方式。它非常容易出错 - 如果混淆索引会发生什么?或者类型改变?

最好使用实际的类,元组或ValueTuples,例如:

var myList = new List<(string,string)>{
    ("Foo", "1" ),
    ("Boo", "2" ),
    ("Foo", "3" ),
    ("Boo", "4" ),
};

var myLinq = myList
    .OrderBy(x => x.Item1)
    .GroupBy(x => x.Item1)
    .Select(y => new
    {
        Key = y.Key,
        Value = y.Sum(x => int.Parse(x.Item2))
    });

var myList = new List<(string key,string value)>{
    ("Foo", "1" ),
    ("Boo", "2" ),
    ("Foo", "3" ),
    ("Boo", "4" ),
};

var myLinq = myList
    .GroupBy(x => x.key)
    .OrderBy(x => x.Key)
    .Select(y => new
    {
        Key = y.Key,
        Value = y.Sum(x => int.Parse(x.value))
    });

注意上次查询中GroupBy,OrderBy顺序的变化。现在我可以看到每个字段的作用,我可以通过键名 订购组并获取:

Boo 6 
Foo 4 

答案 2 :(得分:-2)

为什么要创建一个词典?

var myList = new List<string[]>();
myList.Add(new string[] { "Foo", "1" });
myList.Add(new string[] { "Boo", "2" });
myList.Add(new string[] { "Foo", "3" });
myList.Add(new string[] { "Boo", "4" });

Console.WriteLine("Foo count: " + myList.Where(l => l[0] == "Foo").Count());
Console.WriteLine("Boo count: " + myList.Where(l => l[0] == "Boo").Count());

或者如果您只想创建字典并将数字用作键

Dictionary<string, string> myDict = new Dictionary<string, string>();
myDict.Add("1", "Foo");
myDict.Add("2", "Boo");
myDict.Add("3", "Foo");
myDict.Add("4", "Boo");

Console.WriteLine("Foo count: " + myDict.Where(l => l.Value == "Foo").Count());
Console.WriteLine("Boo count: " + myDict.Where(l => l.Value == "Boo").Count());