简体   繁体   English

删除对象C#列表中的重复项

[英]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 . 我想比较一个对象列表的元素,删除重复的Item并增加该Item的数量(C#代码),我不知道该使用LinQ,For还是foreach语句:我想删除具有相同FK_ArtikelId的OrderItem并增加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 您必须使用GroupBy linq方法并处理生成的组:给定类

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: 以下linq查询返回您需要的内容:

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: 如果您不想创建新文章,则可以使用结果组中的第一个并将其“ Quantity设置为正确的值:

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... 我没有测试,但这应该可以使您了解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. 这应该给您组articleID,以便您可以轻松获得计数,创建新的合并列表等。

For starters you can't use foreach because you're modifying the list and the Enumerator will throw an exception. 对于初学者,您不能使用foreach因为您正在修改列表,并且Enumerator将引发异常。 You can do the following with Linq: 您可以使用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 . 现在,每个组中的第一个项目将包含具有相同FK_ArticleId的所有项目数量的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: 将“ Quantity属性累积到每个组的第一项中的一种更优雅的解决方案是:

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: 这是我在LinqPad中报废的内容:

结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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