'how to append 2 2d array that are jagged?

/**
 * 
 * @param left
 * @param right
 * @return Returns a new two-dimensional array of characters where rows with the same index in 
 *         the left and right arrays have been combined (row from right array appended to corresponding 
 *         row from left array).
 */
public static char[][] appendLeftRight​(char[][] left, char[][] right){
    
    
    if(left == null && right == null) {
         return null;
    }
    
    int row = left.length > right.length ? left.length : right.length;
    char[][] newArr = new char[row][];
    

    for (int app = 0;app<row;app++) {
        
            newArr[app]=new char[left[app].length+right[app].length];

        
        for(int i =0;i<left[app].length;i++) {
            
            newArr[app][i]=left[app][i];
            
        }
        for(int i =0;i<right[app].length;i++) {
            
            newArr[app][left[app].length+i]=right[app][i];

        }
        
        
    }
        return newArr;

            
        }

public static void main(String[] args){
char[][] left=new char[][] {
        new char[] {'0'},
        new char[] {'0','0','0'},
        new char[] {'0','0'},
        new char[] {'0'}
    };
    char[][] right=new char[][] {
        new char[] {'x'},
        new char[] {'x','x'},
        new char[] {'x','x','x'}
    };

}

code above is what I got so far. It is supposed to return a char 2d array that looks like

0x
000xx
00xxx
0

the code runs fine...until it gets to the last row of newArr. The issue is when the for loop app = 3.

for (int app = 0;app<row;app++) {

        newArr[app]=new char[left[app].length+right[app].length];

this line specifically. Since the length of right is 2, the code crashes since it cannot get the length of what isn't there. I tried many combinations but can't seem to figure out how to get past this bug. Code works fine when right & left have the same length, but other wise it crashes. How can I make it so right[3].length will just = 0 or will just be ignored;



Solution 1:[1]

This happens because left has an array length of 4, but right has an array length of 3. You need to factor in these differences and not try to access an out of bounds index.

Your method could enforce that the passed arrays are the same size, or you could process each array separately and check that it is not out of bounds. Here is a rough solution that would work:

public static char[][] appendLeftRight?(char[][] left, char[][] right){

    if (left == null && right == null){
        return null;
    }

    int row = left.length > right.length ? left.length : right.length;
    System.out.println("Row: "+row);
    char[][] newArr = new char[row][];

    for (int app = 0; app < row; app++){
        
        //Get the new array lengths without going out of bounds
        int newLength = 0;
        if(app < left.length){
            newLength += left[app].length;
        }
        if(app < right.length){
            newLength += right[app].length;
        }
        
        //Create the new array
        newArr[app] = new char[newLength];

        //value to track insert location
        int i = 0;

        //only add left array if it's not out of bounds
        if(app < left.length){
            for ( ; i < left[app].length; i++){
                newArr[app][i] = left[app][i];
            }
        }

        //only add right array if it's not out of bounds
        //Use i as an offset to insert at the correct location
        if(app < right.length){
            for (int j = 0 ; j < right[app].length; j++){
                newArr[app][i] = right[app][j];
                //incriment counter
                i++;
            }
        }
    }
    return newArr;
}

And the results of your inputs are:

System.out.println(Arrays.deepToString(appendLeftRight?(left, right)));

[[0, x],
 [0, 0, 0, x, x],
 [0, 0, x, x, x],
 [0]]

Solution 2:[2]

You're getting an ArrayIndexOutOfBoundsException because the length of right is 3, and so naturally, right[3] doesn't exist. Your code is assuming that left[app] and right[app] exist in every iteration of the outer for loop, which won't be the case. One potential solution could be to check app to make sure it's strictly less than right.length or left.length, then define some variables to prevent nonexistent array accesses:

int rightLength = (app >= right.length) ? 0 : right.length;
int leftLength = (app >= left.length) ? 0 : left.length;

int insertionPoint = 0;

...
newArr[app] = new char[rightLength + leftLength];

if (leftLength > 0) {
    for( ; insertionPoint < left[app].length; insertionPoint++) {

        newArr[app][insertionPoint] = left[app][insertionPoint];

    }
}
            
if (rightLength > 0) {
    for(int i = 0; i<right[app].length; i++) {

        newArr[app][insertionPoint++] = right[app][i];

    }
}

This prevents you from trying to access array elements that don't exist. If we take the example arrays that your main function defines, on the final iteration of the appendLeftRight outer for loop, what happens is that rightLength gets assigned the value 0 because app == 3 and right.length == 3, so the for loop appending the right array elements never runs.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 sorifiend
Solution 2