简体   繁体   English

如何展平2层对象列表并总结其他属性常见的属性

[英]How to flatten 2 tier lists of objects and summing properties where other properties are common

I realise the name of this question is confusing, so let me rather explain my scenario. 我意识到这个问题的名称令人困惑,所以让我来解释一下我的情景。

I have a list of objects. 我有一个对象列表。 This list has an entry for each user. 此列表包含每个用户的条目。 Each user then has a list of categories, and each category has a category id, and some values that have already been calculated. 然后,每个用户都有一个类别列表,每个类别都有一个类别ID,以及一些已经计算过的值。 I need to flatten my objects in a list of categories, where the properties of each category has been summed. 我需要在一个类别列表中展平我的对象,其中每个类别的属性已经加总。 Each user will have the same amount of categories in their lists, and each category will be present in each user's lists (in other words, each user will have the same list of categories, the calculated properties will only be different). 每个用户在其列表中将具有相同数量的类别,并且每个类别将出现在每个用户的列表中(换句话说,每个用户将具有相同的类别列表,计算的属性将仅不同)。

My classes are: 我的课程是:

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; }
}

What I need to achieve is by using Linq (or whatever means will be most efficient) to flatten the data to a single List where the categories are still split up by their respective ID's but categoryValue and categoryValue2 have been totaled respectively. 我需要实现的是使用Linq(或任何最有效的方法)将数据展平为单个List,其中类别仍然按其各自的ID进行拆分,但categoryValue和categoryValue2分别进行了总计。 Hence I get a 2 totaled value per category for all users. 因此,我为所有用户获得每个类别2总计的值。

I have tried doing a for loop as follows: 我试过做一个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....
}

But the t is giving me linq functions, not the properties that I want to sum. 但是t给了我linq函数,而不是我要求的属性。

I have also tried a similar approach using just linq, but after doing the SelectMany, followed by the GroupBy, the succeeding select statement again doesn't expose the category lists's properties. 我也尝试过使用linq的类似方法,但在执行SelectMany之后,接着是GroupBy,后续的select语句再次不公开类别列表的属性。

Many thanks! 非常感谢!

Is this what you want? 这是你想要的吗?

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) gives you a sequence of Group<category> objects. users.SelectMany(u => u.categories).GroupBy(c => c.categoryID)为您提供一Group<category>对象。 Each has a Key property equal to the categoryID for the group, and also implements IEnumerable<category> . 每个都具有等于该组的categoryIDKey属性,并且还实现IEnumerable<category>

The whole thing gives you a flat sequence of anonymous objects with a categoryID property, and two sum properties for the sums of the two category values. 整个过程为您提供了一个具有categoryID属性的平面匿名对象序列,以及两个类别值之和的两个sum属性。 Anonymous classes can be limiting, so depending on what you're doing with the results, you may want to write a new quickie class for that. 匿名类可能是限制性的,因此根据您对结果所做的操作,您可能希望为此编写一个新的quickie类。

And of course if you need to keep the results around for some reason, call ToList() on the results. 当然,如果由于某种原因需要保持结果,请在结果上调用ToList()

You can use LINQ SelectMany method combined woth GroupBy 您可以使用LINQ SelectMany方法组合woth 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();

This will return List<category> with categoryValue and categoryValue2 summed for all users. 这将返回List<category>其中categoryValuecategoryValue2为所有用户求和。

tested it out and it looks like this. 测试了它看起来像这样。 You will get grouped category list with your desired aggregated result. 您将获得具有所需聚合结果的分组类别列表。

    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)
        });

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

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