Linq“group by”在一个Dictionary属性中的值,带有一个键列表

时间:2012-02-24 19:21:40

标签: linq dictionary group-by

我有以下对象列表

List<Obj> source = new List<Obj>();
source.Add(new Obj() { Name = "o1", Attributes = new Dictionary<string, string> { { "attA", "1" }, { "attB", "1" }, { "attC", "1" } } });
source.Add(new Obj() { Name = "o2", Attributes = new Dictionary<string, string> { { "attA", "1" }, { "attB", "2" }, { "attC", "1" } } });
source.Add(new Obj() { Name = "o3", Attributes = new Dictionary<string, string> { { "attA", "1" }, { "attB", "3" }, { "attC", "2" } } });
source.Add(new Obj() { Name = "o4", Attributes = new Dictionary<string, string> { { "attA", "1" }, { "attB", "4" }, { "attC", "2" } } });
source.Add(new Obj() { Name = "o5", Attributes = new Dictionary<string, string> { { "attA", "2" }, { "attB", "5" }, { "attC", "3" } } });
source.Add(new Obj() { Name = "o6", Attributes = new Dictionary<string, string> { { "attA", "2" }, { "attB", "6" }, { "attC", "3" } } });
source.Add(new Obj() { Name = "o7", Attributes = new Dictionary<string, string> { { "attA", "2" }, { "attB", "7" }, { "attC", "4" } } });
source.Add(new Obj() { Name = "o8", Attributes = new Dictionary<string, string> { { "attA", "2" }, { "attB", "8" }, { "attC", "4" } } });

因此我需要按特定属性的值对其进行分组,此外,这些属性的名称保存在单独的列表中,如:

List<string> groupBy = new List<string>() { "attA", "attC" };

我尝试使用

var groups =
       from s in source
       group s by s.Attributes["attA"];

这很好用,返回2组:

  • “1” - “o1 o2 o3 o4”
  • “2” - “o5 o6 o7 o8”

但实际上我需要做的是按“attA”和“attC”(或者groupBy变量中的任何内容)分组并得到以下四组:

  • “1_1” - “o1 o2”
  • “1_2” - “o3 o4”
  • “2_3” - “o4 o5”
  • “2_4” - “o7 o8”

2 个答案:

答案 0 :(得分:4)

from c in source
group c by String.Join("_",groupBy.Select(gr=>c.Attributes[gr]).ToArray()) into gr
select new 
{
   AttrValues = gr.Key,
   //Values = gr.Key.Split('_'),
   Names = gr.Select(c=>c.Name).ToList()
};

组密钥是从 groupBy 键列表中获取的字典值的连接投影。

答案 1 :(得分:0)

您可以按多个属性进行分组:

var groups = from s in source
             group s by new 
             { 
                AttributeA = s.Attributes["attA"], 
                AttributeC = s.Attributes["attC"] 
             };

//shows 4 groups
foreach (var group in groups)
    Console.WriteLine(group.Key.AttributeA + "_" + group.Key.AttributeC);