3
    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 is: Cannot infer type argument(s) for flatMap(Function>)

What is the correct way to write this? I have tried emitting double[] from the map but can't get that to go either. Thanks a bunch.

Eran
  • 387,369
  • 54
  • 702
  • 768
dreamer
  • 69
  • 3

3 Answers3

3

There is a little bug in your code: you mixed i and j in a[i][j]. Changing these indices you get it with:

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 also may use flatMapToDouble(Function.identity()).

Stefan Warminski
  • 1,845
  • 1
  • 9
  • 18
3

You can try this as well:

final double[][] a = new double[][] { { 1, 2, 3 }, { 4, 5, 6 } };
final double[] da = Arrays.stream(a)
    .flatMapToDouble(Arrays::stream)
    .toArray();

It makes a stream of streams and then flat maps it. Advantage of this is that you can have any size nested array.

Note: as Alexis C pointed out it doesn't interleave the elements. You will get the result in the order the elements were in the original array. E.g. [1, 2, 3, 4, 5, 6]

Justas
  • 811
  • 1
  • 11
  • 22
  • 3
    Note that this does not interleave the elements as the OP requires. By the way, you can make it a bit shorter with `Arrays.stream(a).flatMapToDouble(Arrays::stream).toArray();` – Alexis C. Mar 22 '17 at 10:42
  • 1
    Thanks, didn't notice that. Edited the answer to reflect that. – Justas Mar 22 '17 at 11:32
2

This seems to do the 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 didn't work since it expects to map your intermediate Stream<DoubleStream> to a Stream<SomeReferenceType>, which is not possible with your mapping function.

Using flatMapToDouble would transform the Stream<DoubleStream> to a DoubleStream, which can be easily converted to a double[].

Eran
  • 387,369
  • 54
  • 702
  • 768