unknown_dcba
unknown_dcba

Reputation: 135

Combining these two Java streams into one

is there a possibility to combine the two streams in the method into one, so there is only one return statement line? The method should calculate the sum of each column in the given two dimensional double array, insignificant which structure the array has, but the array has at least one element, and non null rows are allowed. Thanks a lot.

public static double[] sumUpCols(double[][] x) {
    double[][] a = Stream.of(x).sorted((a0, a1) -> a1.length - a0.length).toArray(double[][]::new);
    return IntStream.range(0, a[0].length).mapToDouble(i -> IntStream.range(0, a.length).mapToDouble(j -> i < a[j].length ? a[j][i] : 0.0).sum()).toArray();
}

public static void main(String[] args) {
    double[][] x = { { 1 }, { 2, 3 }, { 4, 5, 6 }, { 5, 2 } };
    System.out.println(Arrays.toString(sumUpCols(x)));
}

Upvotes: 2

Views: 296

Answers (4)

Kaplan
Kaplan

Reputation: 3758

lambda with reduction — without the use of map, flatMap or an additional IntStream

public static double[] sumUpCols(double[][] x) {
  double[][] sum = new double[][] { {0}, {} };
  return( Stream.of( x ).reduce( (a1, a2) -> {
    for( int i = 0; i < a1.length || i < a2.length; i++ ) {
      sum[0] = Arrays.copyOf( sum[0], i + 1 );
      sum[0][i] = 0;
      try {
        sum[0][i] += a1[i];
      }
      catch( ArrayIndexOutOfBoundsException ex ) {}  // ignored
      try {
        sum[0][i] += a2[i];
      }
      catch( ArrayIndexOutOfBoundsException ex ) {}  // ignored
    }
    return sum[0];
  } ).get() );
}

enlarges the result-array dynamically
can handle empty rows too

gets: [12.0, 10.0, 6.0]

Upvotes: 0

pero_hero
pero_hero

Reputation: 3194

a boxed trial without sorting the array by converting it to a map where the column index is the key and the value is the sum of the column:

Collection<Double> values = Arrays.stream(x)
      .flatMap(b -> IntStream.range(0, b.length)
                    .mapToObj(i -> new AbstractMap.SimpleEntry<Integer, Double>(i, b[i])))
      .collect(groupingBy(e -> e.getKey(), summingDouble(v -> v.getValue())))
      .values();

Upvotes: 1

MoxxiManagarm
MoxxiManagarm

Reputation: 9134

public static double[] sumUpCols(double[][] x) {
     // return Stream.of(x).mapToDouble((double[] row) -> DoubleStream.of(row).sum()).toArray();

     return Stream.of(x)
            .sorted((a0, a1) -> a1.length - a0.length)
            .reduce((double[] left, double[] right) -> {
                IntStream.range(0, right.length).forEach(i -> left[i] += right[i]);
                return left;
    }).get();
}

Upvotes: 1

Naman
Naman

Reputation: 32036

Not exactly a single stream traversal, yet a slightly better approach could be to identify the max length possible for a nested array. Then iterate using it as indexes and

public static double[] sumUpColumns(double[][] x) {
    return IntStream.range(0, Stream.of(x).mapToInt(a -> a.length).max().orElse(0))
            .mapToDouble(i -> Arrays.stream(x)
                    .mapToDouble(item -> i < item.length ? item[i] : 0.0)
                    .sum())
            .toArray();
}

Upvotes: 0

Related Questions