Home > Net >  Write Java method which merge two 2D Arrays into 1 2D Array
Write Java method which merge two 2D Arrays into 1 2D Array

Time:07-09

I am looking for a method which will merge two 2D arrays into one 2D array.

Arrays may store any types of data.

For example I have:

Object[][] dataProvider = new Object[][]{
                {12, 6.0}, {6, 3.0}
        };

Object[][] impl = new Object[][]{
                {1}, {2}, {3}
        };

As a result should be array below:

Object[][] result = new Object[][]{

{1, 12, 6.0}
{1, 6, 3.0}
{2, 12, 6.0}
{2, 6, 3.0}
{3, 12, 6.0}
{3, 6, 3.0}

 };

here is my code:

public Object[][] merge(Object[][] impl, Object[][] dataProvider) {
        int n = dataProvider.length;
        int m = impl.length;

        Object[][] merged = new Object[m * n][];
        int countLines = 0;

        for (Object[] objects : impl) {
            for (Object[] value : dataProvider) {
                int g = objects.length   value.length;
                List<Object> list = new ArrayList<>();

                for (int j = 0; j < objects.length; j  ) {
                    list.add(j, impl[j]);
                }

                for (int k = 0; k < value.length; k  ) {
                    list.add(list.size(), value);
                }

                merged[countLines] = list.toArray();
                countLines  ;
                list.clear();
            }
        }
        return merged;
    }

The output for merge[0] is [1], [12, 6.0], [12, 6.0] The output should be [1, 12, 6.0]

Could you please help me to find a mistake in the method? Thanks ahead!

CodePudding user response:

You could just concat the rows of your arrays using copy methods:

import java.util.Arrays;

public class Example {

    public static void main(String[] args) {

        Object[][] impl = {{1}, {2}, {3}};

        Object[][] dataProvider = {{12, 6.0}, {6, 3.0}};

        System.out.println(Arrays.deepToString(merge(impl, dataProvider)));
    }

    public static Object[][] merge(Object[][] impl, Object[][] dataProvider) {
        int n = dataProvider.length;
        int m = impl.length;

        Object[][] merged = new Object[m * n][];
        int row = 0;

        for (Object[] objects : impl) {
            for (Object[] value : dataProvider) {
                merged[row  ] = concatArrays(objects, value);
            }
        }

        return merged;
    }

    static Object[] concatArrays(Object[] array1, Object[] array2) {
        Object[] result = Arrays.copyOf(array1, array1.length   array2.length);
        System.arraycopy(array2, 0, result, array1.length, array2.length);
        return result;
    }
}

output:

[[1, 12, 6.0], [1, 6, 3.0], [2, 12, 6.0], [2, 6, 3.0], [3, 12, 6.0], [3, 6, 3.0]]

CodePudding user response:

Using a combination of loops and stream this will merge the two as requested.

Object[][] dataProvider =
        new Object[][] { { 12, 6.0 }, { 6, 3.0 } };
Object[][] impl = new Object[][] { { 1 }, { 2 }, { 3 } };

Object[][] result = merge(impl, dataProvider);

for (Object[] arr : result) {
    System.out.println(Arrays.toString(arr));
}

prints

[1, 12, 6.0]
[1, 6, 3.0]
[2, 12, 6.0]
[2, 6, 3.0]
[3, 12, 6.0]
[3, 6, 3.0]

This will allow the first and second arrays to be merges as described above. Any type is supported.

  • compute the length of the resultant array
  • Allocate a result array
  • stream the two arrays and assign to the appropriate array.
  • return the result.
@SuppressWarnings("unchecked")
public static <T> T[][] merge(T[][] first, T[][] second) {
    int rows = first.length * second.length;
    T[][] result = (T[][]) new Object[rows][];
    int r = 0;
    for (T[] arr : first) {
        for (T[] arr2 : second) {
            result[r  ] = (T[]) Stream.of(arr, arr2)
                    .flatMap(Arrays::stream).toArray();
        }
    }
    return result;
}

CodePudding user response:

The main mistake is that your method's code is very difficult.

Let me introduce you to my solution

    Object[][] merge(Object[][] array1, Object[][] array2) {
        Object[][] result = new Object[array1.length * array2.length][];
        for(int i = 0; i < array1.length;   i)
            for (int j = 0; j < array2.length;   j) {
                result[i * array2.length   j] = merge(array1[i], array2[j]);
            }
        return result;
    }

    Object[] merge(Object[] array1, Object[] array2) {
        return Stream.of(array1, array2)
                .flatMap(Stream::of)
                .toArray(Object[]::new);
    }

merge(impl, dataProvider) gives exactly what you want

  • Related