Reputation: 135
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
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
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
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
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