Flatmap typing - attempting to merge DoubleStreams
final double[][] a = new double[][] { { 1, 2, 3 }, { 4, 5, 6 } };
final int numRows = a.length;
final int numCols = a[0].length;
final double[] da = IntStream.range(0, numCols)
.mapToObj(i -> IntStream.range(0, numRows).mapToDouble(j -> a[i][j])).flatMap(d -> d)
.toArray(double[]::new);
// da should be [1, 4, 2, 5, 3, 6]
Error: cannot call type argument for flatMap (Function>)
What's the correct way to write this? I've tried emitting double [] from the map but can't seem to get it done. Thanks a bunch.
source to share
There is a small mistake in your code: you mixed i
and j
in a[i][j]
. By changing these indices, you get them:
double[] da = IntStream.range(0, numCols)
.mapToObj(i -> IntStream.range(0, numRows).mapToDouble(j -> a[j][i]))
.flatMapToDouble(d -> d)
.toArray();
Instead, flatMapToDouble(d -> d)
you can also use flatMapToDouble(Function.identity())
.
source to share
You can also try:
final double[][] a = new double[][] { { 1, 2, 3 }, { 4, 5, 6 } };
final double[] da = Arrays.stream(a)
.flatMapToDouble(Arrays::stream)
.toArray();
It creates a stream of streams and then flat maps. The advantage of this is that you can have any sized nested array.
Note: as Alexis C indicated that it does not interleave elements. You will get the result in the order in which the elements were in the original array. For example.[1, 2, 3, 4, 5, 6]
source to share
This looks like a trick:
final double[] da = IntStream.range(0, numCols)
.mapToObj(i -> IntStream.range(0, numRows).mapToDouble(j -> a[j][i])).flatMapToDouble(d -> d)
.toArray();
Output:
[1.0, 4.0, 2.0, 5.0, 3.0, 6.0]
Note that flatMap
doesn't work as it expects to map your intermediate Stream<DoubleStream>
to Stream<SomeReferenceType>
, which is not possible with your mapping function.
Usage flatMapToDouble
converts the value Stream<DoubleStream>
to DoubleStream
, which can be easily converted to double[]
.
source to share