2

So I have a class with an array of values, and a list of those classes.

And I want to return the sum (or any other operation) of all the items in the list, also as an array.

E.g. the sum of {1,2,3}, {10,20,30} & {100,200,300} would be {111,222,333}

So, the resulting array's 1st element will be the sum of all the 1st elements in the input arrays, the 2nd element will be the sum of all the 2nd elements in the input arrays, etc.

I can do it with:

    public class Item
    {
        internal int[] Values = new int[3];
    }

    public class Items : List<Item>
    {
        internal int[] Values
        {
            get
            {
                int[] retVal = new int[3];
                for (int x = 0; x < retVal.Length; x++)
                {
                    retVal[x] = this.Sum(i => i.Values[x]);
                }
                return retVal;
            }
        }
    }

But I feel that this should be achievable as a single line using LINQ. Is it?

3
  • items.Select(item => item.Values.Sum()).ToArray() Commented Jul 6, 2020 at 11:38
  • 1
    Surely the um of {1,2,3}, {10,20,30} & {100,200,300} would be 6, 60, 600 ? Commented Jul 6, 2020 at 11:39
  • 1
    Do you want to get an array with sum of every 1th, 3nd,.. n element of Values array? What happens, if the have a different length? Commented Jul 6, 2020 at 11:53

2 Answers 2

4

Yes, this can be done using a single linq code line, using Enumrable.Range, Max, Select and Sum:

Notice I've also included a simple condition to save you from an IndexOutOfRangeException should one of the arrays is a different length than the others.

internal int[] ValuesLinq
{
    get
    {
        return Enumerable
            .Range(0, this.Max(i => i.Values.Length))
            .Select(ind => this.Sum(item => item.Values.Length > ind ? item.Values[ind] : 0))
            .ToArray();
    }
}

You can see a live demo on Rextester

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I never thought of doing the "Enumerable.Range(0, this.Max(i => i.Values.Length))" initial step (and bonus points for it working for any size arrays)
Actually, Dmitry's answer also works for multiple array sizes.
3

You can try to Group items withing the arrays by their indexes (so we sum all 1st arrays items, every 2nd items etc.):

int[] retVal = myList
  .SelectMany(item => item.Values
     .Select((value, index) => new {value, index}))
  .GroupBy(item => item.index, item => item.value)
  .Select(group => group.Sum())
  .ToArray();

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.