Muhammad Vakili
Muhammad Vakili

Reputation: 708

How to sum up every array of a List<int[]> or jagged array via index?

I want to convert this part of code to LINQ. Can anyone help me?

var list = new List<int[]>();
list.Add(new int[] { 1, 2, 3, 4 });
list.Add(new int[] { 5, 4, 2, 1 });
list.Add(new int[] { 5, 9, 3, 5 });

var result = new int[4];
foreach (var item in list)
{
    for (int i = 0; i < 4; i++)
    {
        result[i] += item[i];
    }
}

Result must be : { 11, 15, 8, 10 } because that is the sum-result

Upvotes: 2

Views: 220

Answers (4)

gabba
gabba

Reputation: 2880

Want to do aggregation, so why would not use linq aggregate?

        var list = new List<int[]>();
        list.Add(new int[] { 1, 2, 3, 4 });
        list.Add(new int[] { 5, 4, 2, 1 });
        list.Add(new int[] { 5, 9, 3, 5 });

        var addArrayValues = new Func<int[], int[], int[]>(
            (source, destination) =>
            {
                for (int i = 0; i < source.Length; i++)
                    destination[i] += source[i];

                return destination;
            });

        var aggregateResult = list.Aggregate(new int[4],
            (accumulator, current) => addArrayValues(current, accumulator));

Upvotes: 0

Gilad Green
Gilad Green

Reputation: 37299

First thing that pops to my head:

var list = new List<int[]>();
list.Add(new int[] { 1, 2, 3, 4 });
list.Add(new int[] { 5, 4, 2, 1 });
list.Add(new int[] { 5, 9, 3, 5 });

var result = list.SelectMany(item => item.Select((innerItem, index) => new { index, innerItem }))
                    .GroupBy(item => item.index, (key, group) => group.Sum(item => item.innerItem))
                    .ToList();

Tim's approach above is cleaner and is better

Upvotes: 2

Tim Schmelter
Tim Schmelter

Reputation: 460138

I think this is the most readable version. No need to GroupBy, you can Sum every index of every array:

int[] result = Enumerable.Range(0, 4)
    .Select(index => list.Sum(arr => arr[index]))
    .ToArray();

Since OP is also using a for-loop from 0-3 they all seem to have the same size.

If that's not the case you could use this super safe approach:

int maxLength = list.Max(arr => arr.Length);
int[] result = Enumerable.Range(0, maxLength)
    .Select(index => list.Sum(arr => arr.ElementAtOrDefault(index)))
    .ToArray();

Upvotes: 4

tym32167
tym32167

Reputation: 4881

You can try this one

var list = new List<int[]>();
list.Add(new int[] { 1, 2, 3, 4 });
list.Add(new int[] { 5, 4, 2, 1 });
list.Add(new int[] { 5, 9, 3, 5 });

var result = list.SelectMany(x => x.Select((z, i) => new {z, i}))
    .GroupBy(x=>x.i).Select(x=>x.Sum(z=>z.z)).ToArray();    

Upvotes: 0

Related Questions