Frank Fanelli
Frank Fanelli

Reputation: 351

Sum the base elements of a randomly nested array in Java?

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

Answers (2)

WJS
WJS

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

Samuel Philipp
Samuel Philipp

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

Related Questions