-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
  • 116,971
  • 11
  • 170
  • 194
griips21
  • 125
  • 1
  • 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

4 Answers4

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
  • 27,789
  • 26
  • 218
  • 353
shmosel
  • 49,289
  • 6
  • 73
  • 138
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
  • 43,645
  • 9
  • 78
  • 111
0

I revised the previous code to more KISS and readable.

int[][] nestedArray = {{3, 4, 5, 6}, {1, 2}, {7, 8, 9}};

    LinkedList<Integer> theList = new LinkedList<>();
       for(int[] sList: nestedArray) {
           stream(sList)
                   .forEach(theList::add);
       }
        theList.stream()
                .forEach(e ->System.out.println(e));
Dharman
  • 30,962
  • 25
  • 85
  • 135
Troy Cura
  • 1
  • 2
  • Do you expect an answer to that question? Answer posts are meant only for answering according to [answer]. Please delete this. – Yunnosch Nov 15 '22 at 11:42
  • 1
    @node_modules You edited this post for minor improvements. Can I assume that you see this as an otherwise useful answer? I see an "I want this different structure, can anybody give me the solution for that?" NAA question, even if the author seems to have trouble with finding the "?" on their keyboard. Can you explain how to read this as an answer to the question at the top? (no sarcasm intended, if you can make me see your point I delete my comments and judge this as "looks fine" answer). – Yunnosch Nov 15 '22 at 15:14
  • @Yunnosch I honestly don't mind if you choose to delete or flag it as `looks fine`. I just edited as I think the author of this answer tried to answer and just didn't do any formatting on his answer. If you think this should be deleted, I'm okay with that as well because I cannot edit his whole message and honestly don't even know what he is trying to say – node_modules Nov 15 '22 at 15:20
  • @node_modules You seem to misunderstand "looks fine", which is the opposite of "flaggable". But I would appreciate your explanation how to read this as an answer. It is phrased as a question. It could be a rhetoric question, but the shown code does not strike me as a solution attempt. Again, no sarcasm intended. If you paraphrase the answer you read I will *not* do anything negative. – Yunnosch Nov 15 '22 at 15:25
  • I edited according to authors comment (on their other post) that this is one way to skin the cat. – Yunnosch Nov 16 '22 at 08:39
0

This is another way to do it:

int[][] nestedArray = {{1, 12, 2}, {1, 13, 11, 5, 16}, {7, 8, 9}};
    LinkedList<Integer> theList = new LinkedList<>();
   for(int[] sList: nestedArray) {
       stream(sList)
               .forEach(theList::add);
   }
    theList.stream()
            .forEach(e ->System.out.println(e));
Troy Cura
  • 1
  • 2
  • 2
    Hi Troy Cura. I just noticed that you added this answer after my comment on your other post. This post here looks even more like a question which you want answered instead of an attempt to answer. Can you please make more obvious whether you mean this to be an answer according to [answer]? If not please delete this and your other post on this page. You might also find the [tour] helpful for understanding why I am pestering you with my comments. – Yunnosch Nov 15 '22 at 15:35
  • Hello Yunnosh. thank you. If you checked previous post there was an egoistic answer; as to not hurt some ego; I did it in a question manner like, but posted another solution... In programming... there's a lot of ways to skin a cat... we have to think outside of the box... and we have to make it "KISS" keep it so simple and make your program or code useful even years to come... I was trying to make a different solution with stream, lambda, collections for it... dont want to hurt anybody... have a good day. – Troy Cura Nov 16 '22 at 08:32
  • Could you please [edit] one of your posts into an answer according to [answer] and delete the other one? That does not strictly require to avoid rhetoric questions, but I do recommend to. – Yunnosch Nov 16 '22 at 08:37
  • I edited according to authors comment that this is one (other) way to skin the cat. – Yunnosch Nov 16 '22 at 08:40
  • Troy, I do however not see how "I am looking for a way to code it like this..." (formatting aside) can be part of an answer. – Yunnosch Nov 16 '22 at 08:42