4

I just want to check if there is quicker way using LINQ to have list removed from duplicates by id, but in result list item will have sum of some other property (in this case Price). For example:

Start list:

List<Item> a = new List<Item>
{
   new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
   new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200},
   new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
   new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
   new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
   new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250}
};

And result list would be:

List<Item> a = new List<Item>
{
  new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 200},
  new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200},
  new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 550}
};
1

4 Answers 4

10

In (functional) LINQ it is something like:

List<Item> b = a
    .GroupBy(x => x.Id)
    .Select(x => new Item { Id = x.Key, Name = x.First().Name, Code = x.First().Code, Price = x.Sum(y => y.Price) })
    .ToList();

In keyword-based LINQ it is something like:

List<Item> c = (from x in a
                group x by x.Id into y
                select new Item { Id = y.Key, Name = y.First().Name, Code = y.First().Code, Price = y.Sum(z => z.Price) }
               ).ToList();
6
var filteredList = a.GroupBy(e => e.Id).Select(g =>
{
     var item = g.First();
     return new Item
     {
         Id = item.Id,
         Name = item.Name,
         Code = item.Code,
         Price = g.Sum(e => e.Price)
     };
}).ToList();
2

Something like this will do..

var result = a.GroupBy(it => new { it.Id, it.Name, it.Code })
              .Select(x => new { x.Key.Id,x.Key.Name,x.Key.Code,Price = x.Sum(y=>y.Price)});
-1
public class Item : IEquatable<Item>
    {
        public int? Id { get; set; }
        public string Name { get; set; }
        public string Code { get; set; }
        public int? Price { get; set; }

        public bool Equals(Item Other)
        {
            //Check whether the compared object is null. 
            if (Object.ReferenceEquals(Other, null)) return false;

            //Check whether the compared object references the same data. 
            if (Object.ReferenceEquals(this, Other)) return true;

            //Check whether the products' properties are equal. 
            return this.Id == Other.Id;
        }

        public override int GetHashCode()
        {
            return this.Id.GetHashCode();
        }
    }

List<Item> a = new List<Item>
        {
           new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
           new Item {Id = 2, Name = "Item2", Code = "IT00002", Price = 200},
           new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
           new Item {Id = 1, Name = "Item1", Code = "IT00001", Price = 100},
           new Item {Id = 3, Name = "Item3", Code = "IT00003", Price = 150},
           new Item {Id = 3, Name = "Item3", Code = "IT00004", Price = 250}
        };

        var b = a.Distinct().ToList();
1
  • 1
    Whilst this will get distinct Items based on their ID, it won't do the SUM of price as asked - and will in effect just lose a few items from the collection.
    – GPW
    Commented May 21, 2018 at 13:05

Not the answer you're looking for? Browse other questions tagged or ask your own question.