6

I have some String[] arrays, for example:

['a1', 'a2'] ['b1', 'b2', 'b3', 'b4'] ['c1'] 

How can I mix them, so that I get ['a1', 'b1', 'c1', 'a2', 'b2', 'b3', 'b4'] (0 element of a, then b, c, 1 element of a, b, c and so on)? Thanks

More accurately the resulting array must consist of the first value of the first array, then the first value of the second array, ..., the first value of the last array, the second value of the first array, ..., the second value of the last array, ..., the last value of the biggest array. If arrays are not of the same size, the smaller ones just aren't being taken into account.

Here's an illustration:

a1 a2 a3 a4 b1 b2 b3 b4 b5 b6 b7 c1 c2 d1 d2 d3 d4 d5 Combines into (brackets are just to highlight steps, so they really mean nothing): (a1 b1 c1 d1) (a2 b2 c2 d2) (a3 b3 d3) (a4 b4 d4) (b5 d5) (b6) (b7) 

Also, I'd like to combine variable number of array, not just 3 or 4

1
  • Can you describe more accurate how should they be mixed? Commented Apr 21, 2010 at 10:29

9 Answers 9

17
String result[] = new String[a.length+b.length+c.length]; for (int i = 0, j = 0; j < result.length; ++i) { if (i < a.length) { result[j++] = a[i]; } if (i < b.length) { result[j++] = b[i]; } if (i < c.length) { result[j++] = c[i]; } } 

UPDATE: more generally

String[] merge(String[]... arrays) { int length = 0; for (String[] a: arrays) { length += a.length; } String result[] = new String[length]; for (int i = 0, j = 0; j < length; ++i) { for (String[] a: arrays) { if (i < a.length) { result[j++] = a[i]; } } } return result; } 
Sign up to request clarification or add additional context in comments.

4 Comments

+1 for varargs ... Now make it a generic method, <T> T[] merge(T[]... arrays) and we're talking ;) well done
@basszero: slight issue though: the creation of an array of a generic type is not allowed.
And +1 for using for( String[] a: arrays ).
@akf think again: the first iterations, j will be incremented three times, then two, then one. The number of iterations actually IS the length of the longest array.
1
String[] answer = new String[a.length + b.length + c.length]; int maxLength = Math.max(a.length, Math.max(b.length, c.length)); int counter = 0; for (int i = 0; i < maxLength; i++) { if (i < a.length) answer[counter++] = a[i]; if (i < b.length) answer[counter++] = b[i]; if (i < c.length) answer[counter++] = c[i]; } 

2 Comments

I am not a reputation hunter, but why is the down-vote to a, in my opinion, correct code? At least, leave a comment so I know what I have done wrong.
+1: Actually, this is the most down-to-earth solution I see in this bunch of high-tech answers.
0

If I understand you correctly, you need some function which merges your arrays taking 1 next element from each array if the array has next element.

You'll need to create additional array of indexes (see in example) to track when array has or doesn't have elements to merge:

int[] indexes; //should be initialized with 0's void int[] mergeArrays(int[] ... arrays) { int totalLength = 0; for (int[] array : arrays) { totalLength += array.length; } int[] result = new int[totalLength]; indexes = new int[arrays.length]; //array of indexes int mergeIndex = 0; while (mergeIndex < totalLength) { for (int j = 0; j < arrays.length; j++) { if (indexes[j] != -1) { changed = true; result[mergeIndex++] = arrays[j][indexes[j]]; indexes[j]++; if (arrays[j].length == indexes[j]) { indexes[j] = -1; } } } } return result; } 

Comments

0

From your description (where you need all the 0th elements, then all the 1st, etc, and where the arrays can be of different sizes), then for an easy-to-understand method (but not the most efficient) I would do the following:

  • create a number of Lists each containing the contents of one of the arrays
  • create a List to hold the end result
  • continually cycle through the Lists, removing the 0th element, and adding it to your result List, until none of the lists contain any more elements

You can avoid creating the lists and do things more efficiently by just having an array of indexes that tell you which element you've got up to in each array, but converting to Lists may make the problem easier to conceptualise.

Comments

0

For a task like that, I would probably roll my own. I would create a new String[] with the size of the a.length + b.length + c.length and then use an old-fashioned for loop, iterating Math.max(a.length, Math.max(b.length, c.length)) times. Inside the loop, I would add an element from each, testing the index against the length before doing so to avoid bounds exceptions.

It has also been correctly pointed out elsewhere that you would need to keep track of the index of the last item added to the aggregate array.

Comments

0

To achieve mixed or combined array from two or more you need one empty array to hold the ones you need to combine or mix. Like this:

 String[] lines1; String[] lines2; String[] combined = new String [(lines1.length+lines2.length)]; for (int i = 0, j = 0; j < combined.length; i++) { if (i < lines1.length) { combined[j] = lines1[i]; j++; } if (i < lines2.length) { combined[j] = lines2[i]; j++; } } 

You can shorten the inner condition by assigning to combined[j++] because the incrementing starts afterwards.

Comments

-1
ArrayList al = new ArrayList(); al.Add(array1); al.Add(array2); al.Add(array3); 

that's probably your best bet, or you will run into ArrayIndexOutOfBound-style problems. You'll probably run into this way too

1 Comment

N.B. That won't give the order that the poster wants, though.
-1
 String[] arr0 = ["a1", "a2"]; String[] arr1 = ["b1", "b2", "b3", "b4"]; String[] arr2 = ["c1"]; int length = arr0.length + arr1.length + arr2.length; int max = Math.max(arr0.length, Math.max(arr1.length, arr2.length)); int index = 0; String[] result = new String[length]; for (int i=0; i<max; i++){ if (i<arr0.length) result[index++] = arr0[i]; if (i<arr1.length) result[index++] = arr1[i]; if (i<arr2.length) result[index++] = arr2[i]; } 

1 Comment

This is plain wrong. You must have an auxiliary variable pointing you to the index you are currently writing to in result.
-1

All the answers above are terrible and can be achieved in 3 statements if one reuses System.arraycopy to build an array big enough to hold all the elements from both arrays. After that use the Array.sort methods to sort this big array passing in a Comparator. There is no need to write your own bubble/merge sort when a perfectly fine one already exists.

3 Comments

Although I agree on the uglyness Idea, sorting doesn't help, since the Comparator you refer to would become hideous. It's a mere 'zip' that's needed...
To be honest, I consider your proposition way uglier than the general solution that Maurice Perry posted.
Yes sorry i rushed my answer :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.