使用LINQ分组和合并项目

时间:2019-05-29 02:11:34

标签: c# .net linq

public class Product
{
    public string Code { get; set; }
    public string Name { get; set; }
    public string Amount { get; set; }
}

public List<Product> Products = new List<Product>()
{
    new Product() { Code="A1", Name="Vacuum", Amount = "10" },
    new Product() { Code="A2", Name="Iron", Amount = "20" },
    new Product() { Code="A3", Name="Kettle", Amount = "13" },
    new Product() { Code="A2", Name="Microwave", Amount = "11" },
    new Product() { Code="A3", Name="Dryer", Amount = "3" }
};

我需要选择所有没有重复代码的产品。具有相同代码的产品应合并为一行,在这种情况下,名称和金额应以逗号分隔。如何修改以下代码以使其更优雅

    var list1 = new List<Product>();
    var gl = Products.GroupBy(x => x.Code).Where(x => x.Count() > 1);
    gl.ToList().ForEach(x => list1.AddRange(x));

    var list2 = Products.Where(x => !list1.Contains(x)).ToList(); // uniq values

    var list3 = gl.Select(x =>
    {
        var p = new Product() { Code = x.Key };
        p.Name = string.Join(",", x.ToList().Select(r => r.Name).Distinct());
        p.Amount = string.Join(",", x.ToList().Select(r => r.Amount).Distinct());
        return p;
    }).ToList();

    list2.AddRange(list3);
    list2.ForEach(x =>
    {
        Console.WriteLine($"{x.Code.PadRight(20)},{x.Name.PadRight(20)},{x.Amount.PadRight(20)}");
    });

结果应该是:

Code  Name              Amount
A1    Vacuum            10
A2    Iron, Microwave   20, 11
A3    Kettle, Dryer     13, 3

1 个答案:

答案 0 :(得分:4)

GroupBy上使用Code,然后对其进行迭代以使用string.Join()来组合各个元素。

var results = products
    .GroupBy
    ( 
        p => p.Code
    )
    .Select
    (
        g => new 
        {
            Code = g.Key, 
            Name = string.Join
            (
                ",",
                g.Select( p => p.Name )
            ), 
            Amount = string.Join
            (
                ",", 
                g.Select( p => p.Amount.ToString() )
            )
        }
    );

输出:

A1 Vacuum 10
A2 Iron,Microwave 20,11
A3 Kettle,Dryer 13,3

Link to working example on DotNetFiddle