如何平面化对象的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之后,后续的选择语句仍然没有公开类别列表的属性。
多谢!
这是你想要的吗?
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>
以及所有用户的categoryValue
和categoryValue2
之和。
进行了测试,结果如下所示。您将获得包含所需聚合结果的分组类别列表。
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)
});