-2

I have several bags, each filled with multiple containers of apples, where each container may have 0 or more apples.

public class Bag
{
    public List<Container> Containers { get; set; }
}

public class Container
{
    public List<Apple> Apples { get; set; }
}

public class Apple
{
    public double Weight { get; set; }
}

If I have a collection List<Bag> bags, how can I calculate the total weight of all apples via Linq in C#?

Murray Foxcroft
  • 12,785
  • 7
  • 58
  • 86
haosmark
  • 1,097
  • 2
  • 13
  • 27
  • people are downvoting because there's a `.Sum()` lambda exactly for this. You can likely figure out how to do it by googl-ing around a bit – Don Cheadle Jul 26 '16 at 21:27
  • 3
    Start by writing some code. , BTW: posting your data structure and what you have tried so far are a good things when asking a question – Eser Jul 26 '16 at 21:27
  • 1
    http://stackoverflow.com/questions/4351876/c-sharp-list-of-objects-how-do-i-get-the-sum-of-a-property – Don Cheadle Jul 26 '16 at 21:31

3 Answers3

1
var bags = ...;

var total = bags.Sum(b => b.containers.Sum(c => c.apples.Sum(a => a.weight)) );

Edit: Adding explanation as requested (although the code is explanatory itself and the explanation is redundant):

Read the code from innermost to outer, we are summing apples' weight per container and then the containers' sum and then finally the bags' are totalled: It looks like this:

Bag1
 +-----Container1
 |        +------Apple   10
 |        +------Apple   20
 |----------------------------------
 |      Container Total  30
 +-----Container2
 |         +------Apple   11
 |         +------Apple   22
 |         +------Apple   33
 |----------------------------------
 |      Container Total   66
 |----------------------------------
 | Bag Total              96
... Other bags
 |----------------------------------
    Grand total           ...    
Cetin Basoz
  • 22,495
  • 3
  • 31
  • 39
  • While this code snippet may solve the question, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. Please also try not to crowd your code with explanatory comments, as this reduces the readability of both the code and the explanations! – Blue Jul 27 '16 at 01:09
0
List<Bag> bags = ...
List<Container> containers = bags.SelectMany(bag => bag.Containers);
List<Apple> apples = containers.SelectMany(container => container.Apples);
var totalWeight = apples.Sum(apple => apple.Weight);

The SelectMany extension method is used to flatten a two dimensional data structure into a one dimensional structure before executing the sum

  • 1
    `I have several bags`. Question is not about `List>` *bags->containers->apples* .... So, mentioning only `SelectMany` doesn't provide an answer. – Eser Jul 26 '16 at 21:34
  • The outer list corresponds to several bags, the inner List corresponds to the containers within those bags. The important thing to consider here is the `SelectMany` call, which enables the `Sum` extension to operate over all the items in the 2D collection – Bradley Moorfield Jul 26 '16 at 21:35
  • 2
    BTW: Why do you answer a question which doesn't show any effort to search. To encourage lazyness? – Eser Jul 26 '16 at 21:39
  • The answer is simple, but the question is not necessarily easy to search for. A quick search of my own, and those linked by others do not give obvious relevant results. The question could be modified to make it easier for others to find a solution. – Bradley Moorfield Jul 26 '16 at 21:53
  • Don't you think, at least, the sample code like in other answer should have been posted in question? – Eser Jul 26 '16 at 21:56
  • I think the first part of the question describes the problem perfectly fine, both jdweng and I ended up with exactly the same structure in our answers from the description alone – Bradley Moorfield Jul 26 '16 at 22:00
  • The problem is OP doesn't show any effort and make us to create the structure(this is the lazyness). A good question would be, posting the `List bags ......` and the code he has tried so far and asking "how can I do that". Since you can guess the what OP wants to ask doesn't make it a good question. – Eser Jul 26 '16 at 22:04
  • That kind of answers only encourage "write it for me" type of questions – Eser Jul 26 '16 at 22:07
  • Eser, my effort was taking a problem that I have and simplifying it to what you've read. It's a one line linq that I don't know how to write, so what do you expect from me? Do you really need me to say "Ugh, I know there's a Sum(), so maybe bag.container.apples.sum(a => a.weight)." Would that really add anything? And this isn't simple to find in google due to how nested the data is. The reason I posted it here, is because a question like this is better suited for humans, not because I'm "lazy." – haosmark Jul 27 '16 at 13:16
-1

Try this

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Bag> bags = new List<Bag>() {
                new Bag() { containers = new List<Container>() {
                    new Container() { apples = new List<Apple>() {
                        new Apple() { weight = 1.0},
                        new Apple() { weight = 1.2},
                        new Apple() { weight = 1.3}
                    }},
                    new Container() { apples = new List<Apple>() {
                        new Apple() { weight = 0.9},
                        new Apple() { weight = 1.15}
                    }}
                }},
                new Bag() { containers = new List<Container>() {
                    new Container() { apples = new List<Apple>() {
                        new Apple() { weight = 1.0},
                        new Apple() { weight = 1.2},
                        new Apple() { weight = 1.3}
                    }},
                    new Container() { apples = new List<Apple>() {
                        new Apple() { weight = 0.9},
                        new Apple() { weight = 1.15}
                    }}
                }}
            };

            double total = bags.Select(x => x.containers.Select(y => y.apples.Select(z => z.weight))).SelectMany(a => a).SelectMany(b => b).Sum();
        }
    }
    public class Bag
    {
        public List<Container> containers { get; set; }
    }
    public class Container
    {
        public List<Apple> apples { get; set; }
    }
    public class Apple
    {
        public double weight { get; set; }
    }

}
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • `var totalWweight = bags.SelectMany(x => x.containers).SelectMany(x => x.apples).Sum(x => x.weight);` would be more readable (as mentioned in other answer)... – Eser Jul 26 '16 at 21:56