-5

Imagine we have two arrays:

String[] arr1 = {"a", "b"};
String[] arr2 = {"1", "2", "3"};

What is the better way to get the third String array that contains multiplied values of both. Like:

String[] arr3 = {"a1", "a2", "a3", "b1", "b2", "b3"};

I know, I can use cycles and concatenate each element from 1 with each from 2 and put the result in the 3. But actually there are much more elements in the arr1 and in arr2. Is there a special instrument in Java to make it more efficiently?

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Sergey Lotvin
  • 179
  • 1
  • 14
  • 2
    Post the code you have so far. Are you using Java 8? – Tunaki Dec 17 '15 at 19:21
  • http://stackoverflow.com/questions/32631602/cartesian-product-of-streams-in-java-8-as-stream-using-streams-only you might find this useful. However, you would need to convert arrays to streams back and forth. – Krystian Laskowski Dec 17 '15 at 19:23
  • http://stackoverflow.com/questions/14017779/how-to-concat-2-arraylists no better way as far as i know –  Dec 17 '15 at 19:32
  • why the downvotes? I find it a nice question, especially for a new user – vefthym Dec 17 '15 at 19:39
  • @dacrovinunghi OP is not asking to concatenate the lists, but to cross-join the lists. – Andreas Dec 17 '15 at 19:39
  • oups you're right, the same code just 2 loops or lambda –  Dec 17 '15 at 19:42

3 Answers3

5

If you can use Java 8, this is a one-liner:

public static void main(String[] args) {
    String[] arr1 = {"a", "b"};
    String[] arr2 = {"1", "2", "3"};
    String[] result = Arrays.stream(arr1).flatMap(s1 -> Arrays.stream(arr2).map(s2 -> s1 + s2)).toArray(String[]::new);
    System.out.println(Arrays.toString(result));
}

The logic is that each element of the first array is mapped to a Stream of all the elements of the second array prepended by this element. This Stream is then flattened and collected into an array.

Otherwise, although you did not post the code you currently have, it sounds like a good way to do it and there are no magic methods in Java to do it simpler.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
1
    int z = 0;
    String[] suit_arr = {"C", "D", "H", "S"};
    String[] rank_arr = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"};
    String[] pack = new String[52];
    for (int i = 0; i < suit_arr.length; i++) {
        for (int j = 0; j < rank_arr.length; j++) {
            pack[z] = suit_arr[i] + rank_arr[j];
            z++;
        }

    }
    for (int y = 0; y < pack.length; y++) {
        System.out.println(pack[y]);
    }

}

It's for card pack. So it's not just concatenate it's like I have to get all possible mix between each elements of the arrays. P.S.: by the by, why I got minuses for the question? Is it stupid question or what?

Sergey Lotvin
  • 179
  • 1
  • 14
  • 1
    Is this the code you currently have? If so, you should post it in your question instead. – Tunaki Dec 17 '15 at 19:44
  • Yeah. I have it now and had not before question. I've written it for example. But I got the idea! Post the code in order advisers could better understande an issue. Am I right? – Sergey Lotvin Dec 17 '15 at 19:47
  • Yes. It also shows that you tried to do something so it makes the question better by providing a base code for answerers to base themselves. If I were to guess, this is probably why your question was downvoted (lack of showing an existing code). – Tunaki Dec 17 '15 at 19:49
  • Gotcha! Thanks! Your example is cool, but I have to read some staff to understand it clearly. But, for sure, I voted for that. – Sergey Lotvin Dec 17 '15 at 19:53
0

There is no more efficient approach than nested loops if you mean "efficient" in the sense of asymptotic complexity. No matter what, you need to generate and record references to arr1.length * arr2.length strings, and in the best best case that requires work proportional to the number of elements; that is, it is o(arr1.length * arr2.length). The nested loop approach exhibits the best-case complexity already.

You can also solve the problem with Java 8 streams, however, which could be expressed more compactly and (to some) more clearly. That also affords an entry into parallelizing the operation, so although it does not reduce the asymptotic complexity (and it probably has somewhat higher overall cost), if you mean "efficient" in the sense of less wall time then streams might be what you are looking for. Another answer already provides details.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157