-2

Given the following two dimensional array

int[][] arr = {{1, 2}, {3, 4}, {5, 6}};

How can I flatten it column-by-column using the Java 8 Stream API? I want to get:

int[] result = {1, 3, 5, 2, 4, 6};

I tried doing a simple flatMap, but this flattens row-by-row and results in the wrong order:

// result is { 1, 2, 3, 4, 5, 6 }
int[] result = Arrays.stream(arr)
    .flatMapToInt(Arrays::stream)
    .toArray();

I considered transposing the array first so that I can use the above snippet, but creating an intermediate, transposed copy of the array seems unnecessary. How can I flatmap by column directly?

It can be assumed that all the nested arrays are of same length.

that other guy
  • 109,738
  • 11
  • 156
  • 185
griips21
  • 125
  • 6
  • 1
    *Most elegant way:* Nested loops. (my opinion) – Andreas Feb 28 '19 at 21:04
  • What did you try, and why isn't that good enough? – Andreas Feb 28 '19 at 21:06
  • 1
    @Nikolas If you have a point to make, please do so directly. – that other guy Feb 28 '19 at 21:13
  • I basically did it like this IntStream.range(0, 2).forEach(i -> Arrays.stream(arr).map(subArr -> subArr[i]).forEach(System.out::println)); But i feel like it could be more elegant – griips21 Feb 28 '19 at 21:14
  • @thatotherguy: A direct use of `Stream::flatMap` here results in `1, 2, 3, 4, 5, 6`, yet the desired output is `1, 3, 5, 2, 4, 6`. – Nikolas Charalambidis Feb 28 '19 at 21:21
  • @thatotherguy: Then how this question differs from [this](https://stackoverflow.com/questions/13210880/replace-one-substring-for-another-string-in-shell-script?rq=1) or [this](https://stackoverflow.com/questions/5878952/cast-int-to-enum-in-java?rq=1)? My point is that you care more about *how* is it asked about helping the OP to reformulate the question to match the current standards. – Nikolas Charalambidis Mar 01 '19 at 09:08
  • 2
    @Nikolas I agree entirely. I wouldn't (and didn't) downvote this, and I don't think it's warranted. Re-reading the question more carefully didn't help me see that this is what you meant though, so chances are it would have been more effective to state this directly – that other guy Mar 01 '19 at 21:27

2 Answers2

4

You can stream the inner indexes and flatMap to each outer array:

IntStream.range(0, arr[0].length)
        .flatMap(i -> Arrays.stream(arr).mapToInt(a -> a[i]))
        .toArray()
Naman
  • 21,685
  • 24
  • 196
  • 332
shmosel
  • 45,768
  • 6
  • 62
  • 130
1

If we assume that all the nested arrays are of the same length we can use nested loops:

int[][] arr = {{1, 2}, {3, 4}, {5, 6}};
int[] res = new int[arr.length * arr[0].length];
int j = 0;
for (int i = 0; i < arr[0].length; i++) {
  for (int[] a : arr) {
    res[j++] = a[i];
  }
}
System.out.println(Arrays.toString(res)); // [1, 3, 5, 2, 4, 6]
Karol Dowbecki
  • 41,216
  • 9
  • 68
  • 101