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

Fluffy
  • 27,504
  • 41
  • 151
  • 234

9 Answers9

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;
}
Maurice Perry
  • 32,610
  • 9
  • 70
  • 97
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];
}
Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
  • 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. – Petar Minchev Apr 21 '10 at 10:57
  • 1
    +1: Actually, this is the most down-to-earth solution I see in this bunch of high-tech answers. – xtofl Apr 21 '10 at 11:40
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.

akf
  • 38,619
  • 8
  • 86
  • 96
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;
}
Roman
  • 64,384
  • 92
  • 238
  • 332
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.

Neil Coffey
  • 21,615
  • 7
  • 62
  • 83
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.

Denise Ignatova
  • 465
  • 4
  • 7
-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

David Fox
  • 10,603
  • 9
  • 50
  • 80
-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];
    }
Martin Konecny
  • 57,827
  • 19
  • 139
  • 159
  • This is plain wrong. You must have an auxiliary variable pointing you to the index you are currently writing to in result. – Petar Minchev Apr 21 '10 at 10:43
-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.

mP.
  • 18,002
  • 10
  • 71
  • 105
  • 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... – xtofl Apr 21 '10 at 11:12
  • To be honest, I consider your proposition way uglier than the general solution that Maurice Perry posted. – Petar Minchev Apr 21 '10 at 11:16
  • Yes sorry i rushed my answer :) – mP. Apr 21 '10 at 11:26