Z.R.T.
Z.R.T.

Reputation: 1603

group and combine items using 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" }
};

I need to select all products without duplicate code. Products with the same code should be combined into one line, in this case name and amount should be separated by commas. How to modify the following code to make it more elegant

    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)}");
    });

the result should be:

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

Upvotes: 1

Views: 64

Answers (1)

John Wu
John Wu

Reputation: 52280

Use GroupBy on Code, then iterate over it to get the individual elements to combine using 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() )
            )
        }
    );

Output:

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

Link to working example on DotNetFiddle

Upvotes: 4

Related Questions