Home > OS >  How to Merge Three Arrays in java?
How to Merge Three Arrays in java?

Time:09-18

I have three arrays like the below: int a[] = {1,2,3,4}; int b[] = {5,6,7,8}; int c[] = {9,10,11,12};

I want to merge above arrays to get the below result: int d[] = {1,5,9,2,6,10,3,7,11,4,8,12};

I have coded it as below but it is concatenated:

public class MergeTwoArrays2 {
public static void main(String[] args)
{

    int a[] = {1,2,3,4};
    int b[] = {5,6,7,8};
    int c[] = {9,10,11,12};

    int a1 = a.length;
    int b1 = b.length;
    int c1 = c.length;

    int d1 = a1   b1  c1;

    
    int[] d = new int[d1];


    for (int i = 0; i < a1; i = i   1) {
        d[i] = a[i];
    }

    
    for (int i = 0; i < b1; i = i   1) {
        d[a1   i] = b[i];
    }

    for (int i = 0; i < c1; i = i   1) {
        d[a1   b1   i] = c[i];
    }


    for (int i = 0; i < d1; i = i   1) {

        System.out.println(d[i]);
    }
}
}

OUTPUT: [1,2,3,4,5,6,7,8,9,10,11,12]

Expected Output:

[1,5,9,2,6,10,3,7,11,4,8,12]

CodePudding user response:

So you want to take the first element from all three arrays a, b, c, then the second one, and so on.

For that, you need a different strategy of populating the array d.

You can iterate over all your arrays simultaneously checking if the next element exists in a particular array, and if it's the case assigning it to the current position in the resulting array.

int[] d = new int[d1];
    
for (int i = 0, j = 0; i < Math.max(Math.max(a1, b1), c1);i  ) {
    if (i < a1)  d[j  ] = a[i];
    if (i < b1)  d[j  ] = b[i];
    if (i < c1)  d[j  ] = c[i];
}
    
System.out.println(Arrays.toString(d));

Output:

[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]

In the case when all the given arrays a, b, c are of the same length, you can get rid of the if-statements:

for (int i = 0, j = 0; i < a1; i  ) {
    d[j  ] = a[i];
    d[j  ] = b[i];
    d[j  ] = c[i];
}

Generalizing the problem

Your problem can be generalized to merging an arbitrary number of integer arrays having the same length.

That would allow eliminating duplicated statements and hard-coded names.

/**
 * Merges arbitrary number of arrays of the same length
 */
public static int[] joinAll(int[]... arrays) {
    if (arrays.length == 0) return new int[0];

    int[] result = new int[arrays.length * arrays[0].length];

    for (int i = 0, j = 0; i < arrays[0].length; i  ) {
        for (int[] arr: arrays) {
            result[j  ] = arr[i];
        }
    }
    return result;
}
System.out.println(Arrays.toString(joinAll(a, b, c)));

Output:

[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]

Stream-based solution

In case if you fill comfortable with Stream IPA you represent the logic from generalized method shown above using a single statement:

/**
 * Merges arbitrary number of arrays of the same length
 */
public static int[] joinAll(int[]... arrays) {
    if (arrays.length == 0) return new int[0];
    
    return IntStream.range(0, arrays[0].length)
        .flatMap(i -> Arrays.stream(arrays).mapToInt(arr -> arr[i]))
        .toArray();
}

CodePudding user response:

With java streams you can do that in that way:

var aMap = IntStream.range(0, a.length)
        .boxed()
        .collect(Collectors.toMap(i -> i, i -> a[i], (x, y) -> y));

var bMap = IntStream.range(0, b.length)
        .boxed()
        .collect(Collectors.toMap(i -> i, i -> b[i], (x, y) -> y));

var cMap = IntStream.range(0, c.length)
        .boxed()
        .collect(Collectors.toMap(i -> i, i -> c[i], (x, y) -> y));

var collect = Stream.of(aMap, bMap, cMap)
        .flatMap(map -> map.entrySet().stream())
        .collect(Collectors.groupingBy(Map.Entry::getKey))
        .values().stream()
        .flatMap(Collection::stream).map(Map.Entry::getValue).toList();
  • Related