说我有一个Person
类
public class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
如何按动态范围分组? (例如,从最年轻的人开始,我想按5的范围分组,所以如果最年轻的人是12,那么这些组将是12-17,18-23 ....)
如何确定Key
接口的IGrouping
? (例如,将每个组的Key
设置为该组中的平均年龄)
答案 0 :(得分:3)
要获得分组键,您可以创建一个函数:
String GetAgeInterval(Int32 age, Int32 minimumAge, Int32 intervalSize) {
var group = (age - minimumAge)/intervalSize;
var startAge = group*intervalSize + minimumAge;
var endAge = startAge + intervalSize - 1;
return String.Format("{0}-{1}", startAge, endAge);
}
假设最小年龄为12且间隔大小为5,那么对于年龄介于12和16(含)之间的年龄,函数将返回字符串12-16
,年龄介于17和21之间(包括),函数将返回字符串17-21
等。或者您可以使用间隔大小为6来获取间隔12-17,18-23等。
然后您可以创建组:
var minimumAge = persons.Min(person => person.Age);
var personsByAgeIntervals = persons
.GroupBy(person => GetAgeInterval(person.Age, minimumAge, 5));
要获得每组的平均年龄,您可以执行以下操作:
var groups = personsByAgeIntervals.Select(
grouping => new {
AgeInterval = grouping.Key,
AverageAge = grouping.Average(person => person.Age),
Persons = grouping.ToList()
}
);
这将创建一个由匿名类型表示的组序列,其中包含属性AgeInterval
,AverageAge
和Persons
。
答案 1 :(得分:1)
使用Linq而不是IGrouping(我从来没有使用过这个界面,所以我没想到帮助你成为最好的开始时间)。我添加了一个配置类来设置最小/最大年龄以及基本描述符。
public class GroupConfiguration {
public int MinimumAge { get; set; }
public int MaximumAge { get; set; }
public string Description { get; set; }
}
我创建了一个Person(人员)列表,并用一些示例记录填充它。
List<Person> people = new List<Person>() {
new Person(12, "Joe"),
new Person(17, "Bob"),
new Person(21, "Sally"),
new Person(15, "Jim")
};
然后我创建了一个GroupConfiguration(配置)列表,并用3个逻辑对我的记录填充它。
List<GroupConfiguration> configurations = new List<GroupConfiguration>() {
new GroupConfiguration() {MinimumAge = 0, MaximumAge=17, Description="Minors"},
new GroupConfiguration() {MinimumAge = 18, MaximumAge=20, Description="Adult-No Alcohol"},
new GroupConfiguration() {MinimumAge = 21, MaximumAge=999, Description="Adult-Alcohol"},
};
然后我将它们加载到字典中,以维护配置与匹配该配置的结果之间的关系。这使用Linq查找与MinimumAge&lt; = age&lt; = MaximumAge匹配的人员的记录。如果有MinimumAge和Maximum Age重叠,这将允许某人被置于多个结果中。
Dictionary<GroupConfiguration, IEnumerable<Person>> groupingDictionary = configurations.ToDictionary(groupConfiguration => groupConfiguration, groupConfiguration
=> people.Where(x => x.Age >= groupConfiguration.MinimumAge && x.Age <= groupConfiguration.MaximumAge));
在控制台程序中抛出此内容,我验证了Minors组中有3个人,成人 - 无酒精组中有0人,成人 - 酒精组中有1人。
foreach (var kvp in groupingDictionary) {
Console.WriteLine(kvp.Key.Description + " " + kvp.Value.Count());
}
Console.ReadLine();