添加字段时的C#逻辑问题

时间:2018-12-18 18:23:04

标签: c#

我有一个包含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;
}

3 个答案:

答案 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