我有一个包含4条记录的列表。如果有相同年龄的动物,我需要添加它们的年龄并将其添加为单独的列。例如,查看下表。
名称|年龄|性别
蚂蚁| 9 | M
蚂蚁| 2 | M
狮子| 8 | M
PIG | 1 | F
有2条重复的记录(Ant)。我需要添加重复项的年龄,因此,会有一个新记录,如:
蚂蚁| 11 | M
总共应该有5条记录以及新添加的行(在上面添加)。
我面临的问题是,我能够添加新添加的记录(通过添加“年龄”字段)。但是,此记录将覆盖初始字段中的第一条记录。如何将该记录添加为新字段。
到目前为止,我的代码:
foreach (var animal in duplicates)
{
Animal ani = listAnimals.First(a=> a.Name.Equals(animal.Name));
ani.Age += animal.Age;
}
答案 0 :(得分:1)
您可以使用Linq轻松完成
假设您的动物类型被声明为
public class Animal
{
public string Name {get;set;}
public int Age{get;set;}
public string Gender {get;set;}
}
您可以按名称将重复项分组并计算年龄总和。
var list = new List<Animal>{
new Animal{Name="Ant",Age=9,Gender="M"},
new Animal{Name="Ant",Age=2,Gender="M"},
new Animal{Name="Lion",Age=8,Gender="M"},
new Animal{Name="Pig",Age=1,Gender="F"},
};
list.AddRange( list.GroupBy(x=>x.Name)
.Where(x=>x.Count()>1)
.Select(x=> new Animal{Name = x.First().Name, Gender= x.First().Gender, Age = x.Sum(c=>c.Age)}));
输出
Name Age Gender
Ant 9 M
Ant 2 M
Lion 8 M
Pig 1 F
Ant 11 M
答案 1 :(得分:0)
var animals = new List<Animal>
{
new Animal { Name = "Ant", Age = 9, Gender = "M"},
new Animal { Name = "Ant", Age = 2, Gender = "M"},
new Animal { Name = "Lion", Age = 8, Gender = "M"},
new Animal { Name = "PIG", Age = 1, Gender = "F"},
};
var new_animals =
from animal in animals
group animal by animal.Name into grp
where grp.Count() >= 2
select new Animal
{
Name = grp.Key,
Age = grp.Sum(a => a.Age),
Gender = "M"
};
animals.AddRange(new_animals);
foreach(var animal in animals)
{
WriteLine(animal);
}
答案 2 :(得分:0)
您的代码将覆盖现有动物,因为您没有使用new Animal()
为总数创建新动物。
在重复项下方的正确位置获取重复项总数非常棘手。为此,我将创建一个源自Animal
的新类,以便能够将动物与总数记录区分开来。
class Animal
{
public string Name { get; set; }
public int Age { get; set; }
public string Gender { get; set; }
}
class AnimalTotals : Animal
{
}
创建重复的总计,如下所示:
var duplicateTotals = listAnimals
.GroupBy(a => (a.Name, a.Gender))
.Where(g => g.Count() > 1)
.Select(g => new AnimalTotals {
Name = g.Key.Name,
Age = g.Sum(a => a.Age),
Gender = g.Key.Gender
});
请注意,我正在使用值元组(在C#7.0中引入)来创建由名称和性别组成的组键。
然后,我将重复的总计与现有列表合并,并对结果进行排序,以使总计低于重复项。
listAnimals = listAnimals
.Concat(duplicateTotals)
.OrderBy(a => a.Name)
.ThenBy(a => a.Gender)
.ThenBy(a => a is AnimalTotals ? 1 : 0)
.ToList();
使用此示例数据
var listAnimals = new List<Animal> {
new Animal{ Name="Ant", Age = 9, Gender = "M" },
new Animal{ Name="Ant", Age = 2, Gender = "M" },
new Animal{ Name="Ant", Age = 5, Gender = "F" },
new Animal{ Name="Ant", Age = 1, Gender = "F" },
new Animal{ Name="Lion", Age = 8, Gender = "M" },
new Animal{ Name="Pig", Age = 1, Gender = "F" },
};
的输出
foreach (Animal a in listAnimals) {
if (a is AnimalTotals) {
Console.WriteLine($"{a.Name} {a.Gender} totals: {a.Age,4}");
} else {
Console.WriteLine($"{a.Name,-6} {a.Age,2} {a.Gender}");
}
}
是
Ant 5 F
Ant 1 F
Ant F totals: 6
Ant 9 M
Ant 2 M
Ant M totals: 11
Lion 8 M
Pig 1 F