我有一个名为Person的类,有2个属性年龄和名称
我试图将人们分为3个不同的年龄组。
我希望我的最终结果是这样的:
YoungGroup (<20 y old):
Person1Name, Age
Person4Name, Age
Person3Name, Age
AdultGroup (20> y <40 old):
Person2Name, Age
Person7Name, Age
Person5Name, Age
SeniorGroup (40> y old):
Person6Name, Age
Person8Name, Age
Person9Name, Age
我只想使用组子句(如果可能的话,也没有加入?(
这就是我尝试的
var multiplegrps = from p in people
group p by p.Age into groups
let age = groups.Key
select new
{
YoungGroup = from p in groups
where age <= 20
group p by p.Age,
AdultGroup = from p in groups
where age >= 21 && age <= 40
group p by p.Age,
SeniorGroup = from p in groups
where age >= 41
group p by p.Age
};
它是有效的,或者我实际上不知道如何打印它:
foreach (var item in multiplegrps)
{
foreach (var i in item.YoungGroup)
{
Console.WriteLine($"{i.Key}");
}
}
我确实得到了正确的键,但是我无法访问这些名称,我必须为每个组编写3个内部foreach
P.S。我只想使用纯查询来完成,没有lambdas没有新的扩展方法
P.S。我解决了它,并从@khoroshevj获得了有关使用多个三元操作员的想法,就像:
一样简单 var peopleMultiGrouping = from p in people
let ageSelection =
p.Age < 20
? "Young"
: p.Age >= 20 && p.Age <= 40
? "Adult"
: "Senior"
group p by ageSelection;
foreach (var p in peopleMultiGrouping)
{
Console.WriteLine($"{p.Key}");
foreach (var i in p)
{
Console.WriteLine($" {i.Age}");
}
}
您可以做这样的事情
var multiplegrps =
from p in people
let groupName = GetGroupName(p.Age)
group p by groupName
into groups
group groups by groups.Key;
foreach (var group in multiplegrps)
{
foreach (var member in group.SelectMany(i => i))
{
Console.WriteLine($"{group.Key}, {member.Age}, {member.Name}");
}
}
private static string GetGroupName(int age)
{
return age <= 20
? "YoungGroup"
: age <= 40
? "AdultGroup"
: "SeniorGroup";
}
您的解决方案确实可以按照您的预期工作。问题是您打印结果的方式。
在第二级循环中,i
是类型IGrouping<int, Person>
,基本代表具有公共密钥的对象集合。
您在访问它时显然具有Key
属性,但没有Value
属性。
您可以执行另一个嵌套循环以迭代IGrouping
,然后可以访问完整的Person
属性,或者如果您只想将其保持在两级环路上,则可以使用item.YoungGroup
将CC_7弄平进入IEnumerable<Person>
并像这样迭代:
foreach (var item in multiplegrps)
{
foreach (var person in item.YoungGroup.SelectMany(x => x))
{
Console.WriteLine($"Name: {person.Name}, Age: {person.Age}");
}
}
您似乎正在寻找的最终分组输出是3个离散的人,即年轻,成人和高级人士。
对我来说,对每个人进行分类是有意义的每个人都可以分为年龄段:
var classifiedPersons = people
.Select(p => new{
Person = p,
AgeClassification =
p.age <= 20
? "Young"
: p.age <= 40
? "Adult"
: "Senior"
})
.GroupBy(cp => cp.AgeClassification)
.ToDictionary(grp => grp.Key, grp => grp.Select(g => g.Person));
(您可以使用除字符串以外的其他分类,例如在这里枚举(
现在,您可以通过" Young","成人"one_answers"高级"钥匙访问三组。
您可以像这样一般打印出群体:
foreach (var group in classifiedPersons)
{
Console.WriteLine($"Group: {group.Key}:");
foreach (var person in group.Value)
{
Console.WriteLine($" - {person.Name}:");
}
}
看来您想要一个包含所有三个组的匿名对象,例如:
var allGroupsInOneObject = new {
YoungPeople = classifiedPersons["Young"],
AdultPeople = classifiedPersons["Adult"],
SeniorPeople = classifiedPersons["Senior"]
};
一个警告 - 在通过字典键访问组之前,您可能只需要确保组中有任何人。
----------
foreach (var item in multiplegrps)
{
foreach (var yItem in item.YoungGroup)
{
if (item.YoungGroup.Count() > 0 && yItem.ElementAt(0) != null)
{
Console.WriteLine("Young : " + yItem.ElementAt(0).Name);
}
}
foreach (var aItem in item.AdultGroup)
{
if (item.AdultGroup.Count() > 0 &&aItem.ElementAt(0) != null)
{
Console.WriteLine("Adult : " + aItem.ElementAt(0).Name);
}
}
foreach (var sItem in item.SeniorGroup)
{
if (item.SeniorGroup.Count() > 0 &&sItem.ElementAt(0) != null)
{
Console.WriteLine("Senior : " + sItem.ElementAt(0).Name);
}
}
}
我解决了它,并从@khoroshevj获得了有关使用多个三元运算符的想法,就像:
一样简单 var peopleMultiGrouping = from p in people
let ageSelection =
p.Age < 20
? "Young"
: p.Age >= 20 && p.Age <= 40
? "Adult"
: "Senior"
group p by ageSelection;
foreach (var p in peopleMultiGrouping)
{
Console.WriteLine($"{p.Key}");
foreach (var i in p)
{
Console.WriteLine($" {i.Age}");
}
}
您是否尝试过:
var multiplegrps = people.GroupBy(x=> x.age)
.ToDictionary(x=>x.Key,
x=>x.Select(y=>new {
YoungGroup=y.where(z=>z.age<= 20),
AdultGroup=y.Where(z=>z.age >=21 && a.age <= 40),
SeniorGroup=y.Where(z=> z.age >=41)
});
这只是一个主意,没有尝试过...