Reputation: 351
Given a multidimensional array of integers, how can I find the sum of all the base elements? Each array may have a different number of arrays in it, so my algorithm must be flexible to accommodate all possible inputs. A recursive method would seem to be the most elegant solution. Example:
Given:
array = {
{{1,2,3},
{4,5},
{6,7,8}},
{{9},{10}}
}
Return:
55
Note that the length of each sub-array is inconsistent and varies, as well as the depth of the array. This means that traditional loops would not be able to check the length of the array, and recursive methods would not be able to define the number of dimensions the loop has as an initial parameter. Perhaps a recursive loop would need to cast an Object
as an array?
Edit:
The method should also be able to sum an array of ANY number of dimensions. For example, the input array could have three dimensions, or even 7.
Upvotes: 2
Views: 777
Reputation: 40047
Another possibility which does not use streams or lambdas is to write a simple recursive method. Just like others of this nature, type conflicts would only manifest themselves at runtime.
For the following nested array structure:
Integer[][][][] array = { { { { 1, 2, 3
}, { 4, 5, 6
}, { 7, 8, 9
}
}, { { 10, 11, 12,
}, { 13, 14, 15
}, { 16, 17, 19
}
}
}, { { { 20, 21, 22
}, { 23, 24, 25
}
}
}
};
System.out.println(sum(array));
public static int sum(Object[] a) {
int sum = 0;
for (Object o : a) {
if (o instanceof Object[]) {
sum += sum((Object[]) o);
}
if (o instanceof Integer) {
sum += (Integer) o;
}
}
return sum;
}
Prints
307
Upvotes: 0
Reputation: 11050
Using Java Streams you can use just this (assuming your array has 2 dimensions):
int[][] array = {{1, 2, 3}, {4, 5}, {6, 7, 8}, {9, 10}};
int sum = Arrays.stream(array)
.flatMapToInt(Arrays::stream)
.sum();
If your array has 3 dimensions you can extend this to the following:
int[][][] array = {{{1, 2, 3}, {4, 5}, {6, 7, 8}}, {{9}, {10}}};
int sum = Arrays.stream(array)
.flatMap(Arrays::stream)
.flatMapToInt(Arrays::stream)
.sum();
To handle arrays with unknown depth you can use this method to flatten them:
private static Stream<Object> flatMapDynamicArray(Object[] array) {
return Arrays.stream(array)
.flatMap(o -> o.getClass().isArray() ?
flatMapDynamicArray((Object[]) o) :
Stream.of(o));
}
You also could use o instanceof Object[]
instead of o.getClass().isArray()
but for my tests the second one had better performance.
Use this method like this:
Integer[][][] array = {{{1, 2, 3}, {4, 5}, {6, 7, 8}}, {{9}, {10}}};
int sum = flatMapDynamicArray(array)
.mapToInt(i -> (int) i)
.sum();
The result in all cases will be 55
for the array you shared.
Upvotes: 4