C# LINQ列表中的多个分组依据<;T>;然后转换为列表<;T>;
我有以下课程C# LINQ列表中的多个分组依据<;T>;然后转换为列表<;T>;,c#,.net,linq,C#,.net,Linq,我有以下课程 public class Person { public string ID {get; set;} public string Name {get; set;} public string District {get; set;} public string Level {get; set;} } 然后,在我的函数中,我正在编写一个LINQ,将一个人员列表按地区、然后按级别分组到一个相同类型(人员)的新列表中 我想以一种不使用var(使其成为匿名类型)和new的
public class Person
{
public string ID {get; set;}
public string Name {get; set;}
public string District {get; set;}
public string Level {get; set;}
}
然后,在我的函数中,我正在编写一个LINQ,将一个人员列表按地区、然后按级别分组到一个相同类型(人员)的新列表中
我想以一种不使用var(使其成为匿名类型)和new的方式编写它:
差不多
List<Person> persons; \\this already has values
List<Person> grpByP = persons
.GroupBy()
.ToList<Person>(); \\ Linq query to group persons list by District and Level
列出人员\\这已经有了价值
列表grpByP=人
.GroupBy()
.ToList();\ \Linq按地区和级别查询分组人员列表
我只是不知道如何编写grpByP LINQ查询
更新:我希望在grpByP变量的值中保留ID和名称,因为使用匿名类型将只包括地区和级别
任何帮助都将不胜感激。已经解释了如何使用GroupBy
。我将讨论第二部分:“转换为列表
”和“不使用var
”
首先,关于将GroupBy
的结果转换为List
:您不能这样做。GroupBy
操作的结果是一个IEnumerable
(假设您是按string
属性分组的),它本身就是IEnumerable
的IEnumerable
;每个内部IEnumerable
对应于找到的每个键,您可以使用key
属性检查每种情况下的键:
var grouped = persons.GroupBy(p => p.District);
foreach(var group in grouped)
{
Console.WriteLine($"People in disctrict {group.Key}:");
foreach(var person in group)
{
Console.WriteLine(person.Name);
}
}
你可以回去查看未分组人员的完整列表,但我认为这没有多大意义:
var ungrouped = grouped.SelectMany(g => g).ToList<Person>();
var ungroup=group.SelectMany(g=>g.ToList();
关于不使用var
:您当然可以将变量定义为IEnumerable
,但我看不出这样做有什么好处
编辑:如果其他答案表明您实际上想做的是对数据进行排序,而不是对其进行分组,则所有这些都不适用
根据您的评论编辑:“我希望在grpByP变量的值中保留ID和名称,因为使用匿名类型将只包括地区和级别”-GroupBy
不会创建匿名对象,它将保留您提供的原始对象(参见上面的示例)。只有在生成的组中执行类似于.Select(p=>new{p.Discrict})
的操作时,才会创建匿名对象。已经解释了如何使用GroupBy
。我将讨论第二部分:“转换为列表
”和“不使用var
”
首先,关于将GroupBy
的结果转换为List
:您不能这样做。GroupBy
操作的结果是一个IEnumerable
(假设您是按string
属性分组的),它本身就是IEnumerable
的IEnumerable
;每个内部IEnumerable
对应于找到的每个键,您可以使用key
属性检查每种情况下的键:
var grouped = persons.GroupBy(p => p.District);
foreach(var group in grouped)
{
Console.WriteLine($"People in disctrict {group.Key}:");
foreach(var person in group)
{
Console.WriteLine(person.Name);
}
}
你可以回去查看未分组人员的完整列表,但我认为这没有多大意义:
var ungrouped = grouped.SelectMany(g => g).ToList<Person>();
var ungroup=group.SelectMany(g=>g.ToList();
关于不使用var
:您当然可以将变量定义为IEnumerable
,但我看不出这样做有什么好处
编辑:如果其他答案表明您实际上想做的是对数据进行排序,而不是对其进行分组,则所有这些都不适用
根据您的评论编辑:“我希望在grpByP变量的值中保留ID和名称,因为使用匿名类型将只包括地区和级别”-
GroupBy
不会创建匿名对象,它将保留您提供的原始对象(参见上面的示例)。只有在您执行类似于的操作时,才会创建匿名对象。在生成的组中选择(p=>new{p.Discrict})
。从评论中听起来,您只想按地区,然后按级别对列表进行排序。这很容易
List<Person> result = persons.OrderBy(p => p.District).ThenBy(p => p.Level).ToList();
List result=persons.OrderBy(p=>p.District).ThenBy(p=>p.Level.ToList();
从评论中听起来,你只是想按地区,然后按级别对列表进行排序。这很容易
List<Person> result = persons.OrderBy(p => p.District).ThenBy(p => p.Level).ToList();
List result=persons.OrderBy(p=>p.District).ThenBy(p=>p.Level.ToList();
我想你想要的是这样的东西
List<Person> persons = new List<Person>
{
new Person()
{
ID = "1",
Name = "Joe",
District = "Columbia",
Level = "10"
},
new Person()
{
ID = "2",
Name = "Beth",
District = "Columbia",
Level = "10"
},
new Person()
{
ID = "3",
Name = "Jim",
District = "Washington",
Level = "11"
}
}; //this already has values
var grpByP = persons
.GroupBy(p => new { p.District, p.Level })
.Select(g => new
{
g.Key,
People = g.ToList<Person>()
});
foreach (var g in grpByP)
{
Console.WriteLine("Group:");
Console.WriteLine(g.Key.District);
Console.WriteLine(g.Key.Level);
Console.WriteLine("People:");
foreach (Person p in g.People)
Console.WriteLine(p.Name);
Console.WriteLine();
}
Console.ReadLine();
List persons=新列表
{
新人()
{
ID=“1”,
Name=“乔”,
District=“Columbia”,
级别=“10”
},
新人()
{
ID=“2”,
Name=“Beth”,
District=“Columbia”,
级别=“10”
},
新人()
{
ID=“3”,
Name=“吉姆”,
地区=“华盛顿”,
Level=“11”
}
}; //这已经有了价值
风险值grpByP=人
.GroupBy(p=>new{p.District,p.Level})
.选择(g=>new
{
g、 钥匙,
People=g.ToList()
});
foreach(grpByP中的var g)
{
控制台写入线(“组:”);
控制台写入线(g.Key.District);
控制台写入线(g键级);
Console.WriteLine(“人:”);
foreach(p人与g人)
Console.WriteLine(p.Name);
Console.WriteLine();
}
Console.ReadLine();
输出:-
组:
哥伦比亚10
人:
乔
贝丝
组:
华盛顿11
人:
吉姆
我想你在追求这样的东西
List<Person> persons = new List<Person>
{
new Person()
{
ID = "1",
Name = "Joe",
District = "Columbia",
Level = "10"
},
new Person()
{
ID = "2",
Name = "Beth",
District = "Columbia",
Level = "10"
},
new Person()
{
ID = "3",
Name = "Jim",
District = "Washington",
Level = "11"
}
}; //this already has values
var grpByP = persons
.GroupBy(p => new { p.District, p.Level })
.Select(g => new
{
g.Key,
People = g.ToList<Person>()
});
foreach (var g in grpByP)
{
Console.WriteLine("Group:");
Console.WriteLine(g.Key.District);
Console.WriteLine(g.Key.Level);
Console.WriteLine("People:");
foreach (Person p in g.People)
Console.WriteLine(p.Name);
Console.WriteLine();
}
Console.ReadLine();
List persons=新列表
{
新人()
{
ID=“1”,
Name=“乔”,
District=“Columbia”,
级别=“10”
},
新人()
{
ID=“2”,
Name=“Beth”,
District=“Columbia”,
级别=“10”
},
新人()
{
ID=“3”,
Name=“吉姆”,
地区=“华盛顿”,
Level=“11”
}
}; //这已经有了价值
风险值grpByP=人
.GroupBy(p=>new{