"Filter" equal records in a list by adding their quantitative

5
namespace ConsoleApplication10
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Teste> lstTeste = new List<Teste>
            {
                new Teste {Codigo = 1, Quantidade = 10},
                new Teste {Codigo = 2, Quantidade = 10},
                new Teste {Codigo = 1, Quantidade = 10},
                new Teste {Codigo = 3, Quantidade = 10},
                new Teste {Codigo = 2, Quantidade = 10}
            };
        }
    }

    public class Teste
    {
        public int Codigo { get; set; }
        public int Quantidade { get; set; }
    }

I want to create a new list, or remove the repeated items from the original list, but I want to add the quantitative ones.

The "new" list would read:

Codigo = 1, Quantitativo = 20
Codigo = 2, Quantitativo = 20
Codigo = 3, Quantitativo = 10
    
asked by anonymous 22.09.2015 / 22:22

4 answers

6

By using LINQ you can group the items by code and add up the quantity in each group. However, LINQ is only available from version 3.5 and in some cases we need to work with previous versions, so I also made a solution by grouping and summing using Dictionary as a key / value structure to group the items by code and add the quantities directly in the value of the item in the dictionary.

With LINQ

namespace ConsoleApplication10
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Teste> lstTeste = new List<Teste>
            {
                new Teste {Codigo = 1, Quantidade = 10},
                new Teste {Codigo = 2, Quantidade = 10},
                new Teste {Codigo = 1, Quantidade = 10},
                new Teste {Codigo = 3, Quantidade = 10},
                new Teste {Codigo = 2, Quantidade = 10}
            };

            List<Teste> lstAgrupado = lstTeste
                .GroupBy(i => i.Codigo)
                .Select(j => new Teste()
                {
                    Codigo = j.First().Codigo,
                    Quantidade = j.Sum(ij => ij.Quantidade)
                })
                .ToList();
        }
    }

    public class Teste
    {
        public int Codigo { get; set; }
        public int Quantidade { get; set; }
    }
}

No LINQ

namespace ConsoleApplication10
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Teste> lstTeste = new List<Teste>
            {
                new Teste {Codigo = 1, Quantidade = 10},
                new Teste {Codigo = 2, Quantidade = 10},
                new Teste {Codigo = 1, Quantidade = 10},
                new Teste {Codigo = 3, Quantidade = 10},
                new Teste {Codigo = 2, Quantidade = 10}
            };

            Dictionary<int, Teste> agrupamentoSomado = new Dictionary<int, Teste>();

            foreach (Teste item in lstTeste)
            {
                if (agrupamentoSomado.ContainsKey(item.Codigo))
                {
                    agrupamentoSomado[item.Codigo].Quantidade += item.Quantidade;
                }
                else
                {
                    agrupamentoSomado.Add(item.Codigo, item);
                }
            }

            List<Teste> lstAgrupado = new List<Teste>(agrupamentoSomado.Values);
        }
    }

    public class Teste
    {
        public int Codigo { get; set; }
        public int Quantidade { get; set; }
    }
}
    
22.09.2015 / 22:46
3

A response using the extension methods of System.Linq and return with anonymous objects:

var resultado = lstTeste
      .GroupBy(x => x.Codigo)
      .Select(x => new { 
          Quantitativo = x.Sum(y => y.Quantidade), 
          Codigo = x.First().Codigo
      });

See it working here: link

    
22.09.2015 / 22:50
3

I did it in three different ways to choose the one that best suits you:

using System.Collections.Generic;
using System.Linq;
using static System.Console;

namespace ConsoleApplication10 {
    public class Program {
        public static void Main(string[] args) {
            List<Teste> lstTeste = new List<Teste> {
                new Teste {Codigo = 1, Quantidade = 10},
                new Teste {Codigo = 2, Quantidade = 10},
                new Teste {Codigo = 1, Quantidade = 10},
                new Teste {Codigo = 3, Quantidade = 10},
                new Teste {Codigo = 2, Quantidade = 10}
            };

            //Forma declarativa
            WriteLine("Forma declarativa");
            var items = from item in lstTeste
                group item by item.Codigo
                into g
                select new{Codigo = g.Key, Quantidade = g.Sum(item => item.Quantidade)};
            items.ToList().ForEach(item => { WriteLine(
                $"Item: {item.Codigo} Quantidade: {item.Quantidade}"); });

            //forma imperativa
            WriteLine("Forma imperativa");
            var lista = lstTeste.GroupBy(g => g.Codigo).Select(g => new {
                Codigo = g.First().Codigo, Quantidade = g.Sum(g => g.Quantidade) });
            lista.ToList().ForEach(item => { WriteLine(
                $"Item: {item.Codigo} Quantidade: {item.Quantidade}"); });

            //forma com dicionário - Sem LINQ
            WriteLine("Forma com dicionário");
            var dicionario = new Dictionary<int, Teste>();
            foreach (var item in lstTeste) {
                if (dicionario.ContainsKey(item.Codigo)) {
                    dicionario[item.Codigo].Quantidade += item.Quantidade;
                } else {
                    dicionario[item.Codigo] = item;
                }
            }
            foreach (var item in dicionario.Values) {
                WriteLine($"Item: {item.Codigo} Quantidade: {item.Quantidade}");
            }
       }
    }

    public class Teste {
        public int Codigo { get; set; }
        public int Quantidade { get; set; }
    }
}

See running on dotNetFiddle .

    
22.09.2015 / 22:48
1
public static List<Teste> SomarIguais(List<Teste> list)
{
    if(list == null) return null;
    List<Teste> resultado = new List<Teste>();
    foreach(Teste t in list)
    {
        bool nenhum = true;
        foreach(Teste t1 in resultado)
        {
            if(t1.Codigo == t.Codigo)
            {
                nenhum = false;
                t1.Quantidade += t.Quantidade;
            }
        }
        if(nenhum) resultado.Add(t);
    }
    return resultado;
}
    
22.09.2015 / 22:42