Reputation: 587
I have a list of prods like this:
Prod1: Id=1, Name="name1", Color="Blue"
Prod2: Id=1, Name="name1", Color="Green"
Prod3: Id=2, Name="Test2, Color="Red"
What I want to perform is to get reduced list like this:
Prod1: Id=1, Name="name1", Color="Blue, Green"
Prod3: Id=2, Name="Test2, Color="Red"
I always want to take prods with the same id and add up their colors. I feel there is a clever one code line way to do this, but I somehow got stuck with:
productList.GroupBy(p => new { p.Id }).Select(x => x.First()).ToList();
which does not give me an ability to add second color. Will apreciate any help
Upvotes: 6
Views: 11197
Reputation: 2362
An alternative would be to try to edit the first instance of each product in the products list to add all colors from all instances without creating a new anonymous type to hold the data (as per the accepted answer).
Complete code:
public class Program
{
public static void Main()
{
List<Product> products = new List<Product>
{
new Product() {Id = 1, Name="name1", Color="Blue"},
new Product() {Id = 1, Name="name1", Color="Green"},
new Product() {Id = 1, Name="name1", Color="Green"},
new Product() {Id = 2, Name="name2", Color="Red"}
};
var results = from product in products
group product by product.Id into g // there is no need to group by a complex key if product.Id is unique per product
let colors = string.Join(",", g.Select(c=> c.Color).Distinct())
let p = g.First().Color = colors
select g.First();
foreach(var result in results)
Console.WriteLine(result);
}
}
public class Product
{
public int Id;
public string Name;
public string Color;
public override string ToString()
{
return string.Format("Id:\"{0}\", Name:\"{1}\", Color:\"{2}\"", Id, Name, Color);
}
}
This will change in place the value of the "Color" property of the first instance of product with id=1 discarding any other instances in the list.
It will print:
Id:"1", Name:"name1", Color:"blue,Green"
Id:"2", Name:"name2", Color:"Red"
Working code: https://dotnetfiddle.net/HLtHIE
I am not claiming that this is better or more efficient, but it is worthy alternative.
Upvotes: 0
Reputation: 16956
Try this.
productList.GroupBy(p => new { p.Id, p.Name })
.Select(x =>new {
Id =x.Key.Id,
Name = x.Key.Name,
Color = String.Join(",", x.Select(c=> c.Color))
});
Working Demo
Upvotes: 16