【问题标题】:Combine objects in a list by fields of the objects按对象的字段组合列表中的对象
【发布时间】:2013-05-22 13:03:50
【问题描述】:

我有一个 BillArticle 对象列表,这个类看起来像这样:

public class BillArticle
{
    public int ArticleID { get; set; }

    public string ArticleName { get; set; }

    public double ArticleQuantity { get; set; }

    public double ArticlePrice { get; set; }
}

所以我有一个包含 10 个对象的列表,我想通过重复 ArticleID 和 ArticlePrice 来合并这些对象。

所以我的问题是:我想遍历列表,如果有 2 个或多个具有相同 ArticleID 和相同价格的对象来合并它们(总结 ArticleQuantity)。我现在一直在敲我的头,如果有人能帮我一把,我会很高兴的。提前感谢您的帮助,抱歉我的英语不好。

【问题讨论】:

    标签: c#


    【解决方案1】:

    LINQ 非常适合这种工作 :) 听起来您可能想要这样的东西:

    var merged = list.GroupBy(x => x.ArticleID)
                     .Select(g => new BillArticle { 
                                 ArticleID = g.Key,
                                 ArticleName = g.First().ArticleName,
                                 ArticleQuantity = g.Sum(x => x.ArticleQuantity),
                                 ArticlePrice = g.First().ArticlePrice
                             });
    

    这是假设您确信所有文章的价格和名称都相同。如果没有,您应该考虑如何处理这种情况。

    如果您需要merged 成为List<BillArticle>,只需在末尾添加.ToList()

    编辑:正如安迪的回答中所述,您可以使用匿名类型按文章 ID 和文章价格进行分组。您仍然需要考虑文章名称。如果文章 ID 确实一个标识符,我希望名称和价格无论如何都相同,但这取决于您的业务规则。

    【讨论】:

    • +1,哇,真快。我什至还没有完成 Select 子句中的投影。
    • @乔丹。我试图适应更改以显示如何在评论中同时按ArticleIdArticlePrice 进行分组,但它不适合,我添加了第二个答案。 JonSkeet 的第一个答案是仅按ArticleId 分组。 @JonSkeet,我希望你没问题。
    • @AndyBrown:我永远不会反对某人添加另一个答案——尤其是我显然误读了这个问题:)
    • @JonSkeet。但你是 JonSkeet。当您回答问题时,the question changes to match your answer!!
    【解决方案2】:

    JonSkeet 已经完美地回答了这个问题,可以按单个属性进行分组。我试图在评论中解释按两个或多个属性进行分组,但它不适合,所以我将作为单独的答案来做。

    ArticlePrice 是你可以期望随着时间而改变的东西——资本主义的一个事实经常使我们完美的代码变得不那么完美。你提到:

    2 个或多个具有相同 ArticleID 和相同价格的对象

    这是一个略有不同的要求,因此取决于您回答的问题:

    • 如果您GroupBy(x => x.ArticleID) 您正在回答“我卖出了多少带有ArticleID 12345 的商品”;
    • 如果您同时按 id 和价格分组,您将回答“当它们以 10 美元时,当它们以 20 美元时,我卖出了多少带有 ArticleID12345 的商品......”。

    对于第二种情况,JonSkeet 的代码更改很简单(我已经注意到 // changed here cmets 的更改):

    var merged = list.GroupBy(x => new {x.ArticleID, x.ArticlePrice }) // changed here
                     .Select(g => new BillArticle { 
                         ArticleID = g.Key.ArticleID, // changed here
                         ArticleName = (string)g.First().ArticleName,
                         ArticleQuantity = g.Sum(x => x.ArticleQuantity),
                         ArticlePrice = g.Key.ArticlePrice // changed here
                     });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-30
      • 2022-01-03
      • 1970-01-01
      • 2019-07-15
      • 2020-07-01
      • 2015-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多