Home > Enterprise >  c# iterate list to merge item with same field
c# iterate list to merge item with same field

Time:09-17

So I would have a list of data with matching fields:

class Data
{
   public string type;
   public int amount;
   public Data(string type, int amount)
   {
       this.type = type;
       this.amount = amount;
   }
}


List<Data> list = new List<Data>()
        {
            new Data("A", 20),
            new Data("A", 10),
            new Data("B", 20),
            new Data("B", 20),
            new Data("C", 20)
        };

I would want those items to be merged into one and add the value if they are same type. So I would have "A" => 30, "B" => 40 and "C" => 20.

I can up with this:

    private IEnumerable<Data> MergeDuplicates(IEnumerable<Data> list)
    {
        Dictionary<string, long> dict = new Dictionary<string, long>();
        foreach(Data data in list) 
        {
            if (dict.ContainsKey(data.type)) 
            {
                dict[data.type]  = data.amount;
                continue;
            }
            dict.Add(data.type, data.amount);
        }
        List<Data> newList = new List<Data>();
        foreach(KeyValuePair<string, long> kvp in dict) 
        {
            newList.Add(new Data(kvp.Key, kvp.Value));
        }
        return newList;
    }

It works but it feels longer and more complicated that it should. Particularly when there is no duplicate, it still runs the list back and forth.

I was trying to look into Linq but am not sure of what to search for. It's also not really flexible since it only supports Data type and the predicate is hardcoded in the method.

CodePudding user response:

You could try sth like this, with using GroupBy:

List<Data> list = new List<Data>()
{
    new Data("A", 20),
    new Data("A", 10),
    new Data("B", 20),
    new Data("B", 20),
    new Data("C", 20)
};

var result = list.GroupBy(item => item.type)
                 .Select(gr => new Data(gr.Key, gr.Sum(x=>x.amount)))
                 .ToList();

CodePudding user response:

So this is best solved with Linq.

Add using System.Linq;

And then:

var result = list
            .GroupBy(x => x.type)
            .Select(x => new Data(x.Key, x.Sum(z => z.amount)))
            .ToList();

The result will contain a list of Data with the values you were after

  • Related