简体   繁体   中英

Delete the repeated Item inside a List of object C#

I want to compare the element of a list of object ,delete the repeated Item and increment the number of the quantity of that Item (C# code ), I don't know if I should use LinQ,For or foreach statement : I have a list of OrderItem I want to delete the OrderItem that have the same FK_ArtikelId and increment the Qantity of the OrderItem . Exp:

for (int i=1 ; i < lot.Count   ; i ++)
{
    for (j = i + 1; j <= lot.Count; j++)
    {
        if (lot[i].FK_ArticleId.Equals(lot[j].FK_ArticleId))
        {
            lot[i].Quantity += lot[j].Quantity;
            lot.Remove(lot[j]);
        }
    }
}

You have to use the GroupBy linq method and process the resulting groups: given the class

public class Article
{
    public int FK_ArticleId { get; set; }
    public int Quantity { get; set; }
}

and the following list:

var list = new List<Article>()
{
    new Article() {FK_ArticleId = 1, Quantity = 10}
    , new Article() {FK_ArticleId = 1, Quantity = 10}
    , new Article() {FK_ArticleId = 1, Quantity = 10}
    , new Article() {FK_ArticleId = 2, Quantity = 100}
    , new Article() {FK_ArticleId = 2, Quantity = 100}
    , new Article() {FK_ArticleId = 3, Quantity = 1000}
};

The following linq query returns what you need:

list.GroupBy(a => a.FK_ArticleId)
    .Select(g => new Article() {FK_ArticleId = g.Key, Quantity = g.Sum(a => a.Quantity)});

// article id 1, quantity 30
// article id 2, quantity 200
// article id 3, quantity 1000

If you don't want to create a new article, you can take the first of the resulting group and set its Quantity to the correct value:

var results = list.GroupBy(a => a.FK_ArticleId)
    .Select(g =>
    {
        var firstArticleOfGroup = g.First();
        firstArticleOfGroup.Quantity = g.Sum(a => a.Quantity);
        return firstArticleOfGroup;
    });

I didn't test but this should give you an idea of the power of linq...

 var stuff  = lot
  .GroupBy(p => p.FK_ArticleId)
  .Select(g => g)
  .ToList();

This should give you groups of articleIDs whereby you can easily get counts, create new consolidated lists etc.

For starters you can't use foreach because you're modifying the list and the Enumerator will throw an exception. You can do the following with Linq:

var grouped = lot.GroupBy(x => x.FK_ArticleId).ToArray();
foreach(var group in grouped)
{
    group.First().Quantity = group.Sum(item => item.Quantity);
}

Now, first item in each group will contain the sum of all the quantities of items with the same FK_ArticleId . Now, to get the results use this:

var results = grouped.Select(g => g.First());

At this point it's purely your decision whether to return the results as a separate collection or insert them into the original list. If you opt for the second approach, don't forget to clear the list first:

list.Clear();
list.AddRange(results);

EDIT

A more elegant solution to accumulating the Quantity property into the first item of each group would be the following:

data.GroupBy(x=>x.FK_ArticleId)
    .Select(g => g.Aggregate((acc, item) => 
        {
             acc.Quantity = item.Quantity; 
             return acc;
        }));

This is what I scrapped in LinqPad:

结果。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM