如何平面化对象的2层列表和求和属性,其中其他属性是常见的

本文关键字:属性 其他 常见 平面化 何平 对象 2层 列表 求和 | 更新日期: 2023-09-27 18:09:11

我意识到这个问题的名称令人困惑,所以让我解释一下我的场景。

我有一个对象列表。该列表中每个用户都有一个条目。然后,每个用户都有一个类别列表,每个类别都有一个类别id,以及一些已经计算过的值。我需要在一个类别列表中平面化我的对象,其中每个类别的属性已经被求和。每个用户的列表中将有相同数量的类别,每个类别将出现在每个用户的列表中(换句话说,每个用户将有相同的类别列表,计算的属性将不同)。

我的类是:

public class category {
     public int categoryID { get; set; }
     public decimal categoryValue { get; set; }
     public decimal categoryValue2 { get; set; }
}
public class user {
    public List<category> categories { get; set; }
}

我需要实现的是通过使用Linq(或任何手段将是最有效的)将数据扁平化到单个列表,其中类别仍然由其各自的ID分开,但categoryValue和categoryValue2已分别相加。因此,对于所有用户,我得到每个类别的总价值为2。

我试着做一个for循环,如下所示:

List<category> categoryTotals = new List<category> {};
foreach (category loopCategory in users[0].categories) {
    category currentCategory = new category();
    category = users.Select(x => x.categories).Where(y=>y.categoryID== loopCategory.categoryID)).Select(t => new {t....
}

但是t给出的是linq函数,而不是我想求和的属性

我也尝试过类似的方法,只使用linq,但是在执行SelectMany和GroupBy之后,后续的选择语句仍然没有公开类别列表的属性。

多谢!

如何平面化对象的2层列表和求和属性,其中其他属性是常见的

这是你想要的吗?

var groupSums = 
    from g in users.SelectMany(u => u.categories).GroupBy(c => c.categoryID)
    select new
    {
        categoryID = g.Key,
        CategoryValueSum = g.Sum(c => c.categoryValue),
        CategoryValue2Sum = g.Sum(c => c.categoryValue2),
    };

users.SelectMany(u => u.categories).GroupBy(c => c.categoryID)给出了Group<category>对象的序列。每个都有一个Key属性等于categoryID的组,也实现IEnumerable<category>

整个过程为您提供了一个具有categoryID属性的匿名对象的平面序列,以及两个用于两个类别值之和的sum属性。匿名类可能是有限的,因此根据您对结果的处理,您可能需要为此编写一个新的快速类。

当然,如果您出于某种原因需要保留结果,请对结果调用ToList()

可以将LINQ SelectMany方法与GroupBy方法结合使用

var sumList = users
    .SelectMany(u => u.categories)
    .GroupBy(c => c.categoryID)
    .Select(g => new category()
    {
       categoryID = g.Key,
       categoryValue = g.Sum(z => z.categoryValue),
       categoryValue2 = g.Sum(z => z.categoryValue2),
    })
   .ToList();

这将返回List<category>以及所有用户的categoryValuecategoryValue2之和。

进行了测试,结果如下所示。您将获得包含所需聚合结果的分组类别列表。

    var cats = users.SelectMany(x => x.categories).GroupBy(x => x.CategoryID)
        .Select(x => new Category()
        {
            CategoryID = x.Key,
            CategoryValue = x.Sum(y => y.CategoryValue),
            CategoryValue2 = x.Sum(y => y.CategoryValue2)
        });