Search code examples
javaloopsindexingjagged-arrays

Convert 2D jagged array to proper array Java


I am trying to solve the following problem: I have a 2D jagged array

[[1, 2], [1], [3, 4], [2, 3, 4]]

which I would like to convert to a normal 2D array. Currently, I managed to get this one

[[1, 2, 0, 0], [1, 0, 0, 0], [3, 4, 0, 0], [2, 3, 4, 0]]

but that is not what I want. Goal is to have a normal array indices equaling the original jagged one. In other words, I would like to match the value from the original jagged array to the index starting from 1 in the new proper array. Here is my desired output

[[1, 2, 0, 0], [1, 0, 0, 0], [0, 0, 3, 4], [0, 2, 3, 4]]

Here is my code which produces this array, which is not quite what I would like to have:

[[1, 2, 0, 0], [1, 0, 0, 0], [3, 4, 0, 0], [2, 3, 4, 0]]
import java.util.*;

public class MultiDarrays {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        System.out.println("Get number of two parameters: cyclists and bicycles: ");

        int c = sc.nextInt();
        int b = sc.nextInt();

        System.out.println("cyclists: " + c + " " + "bicycles: " + b);

        ArrayList<ArrayList<Integer>> multilist = new ArrayList<ArrayList<Integer>>();
        for (int i = 0; i < c; i++) {

            List<Integer> integers = new ArrayList<Integer>();
            int num = sc.nextInt();
            for (int j = 0; j < num; j++) {

                int elem = sc.nextInt();
                integers.add(elem);
            }
            multilist.add((ArrayList<Integer>) integers);
        }

        for (int i = 0; i < multilist.size(); i++) {
            System.out.println("Elements are: " + multilist.get(i));
        }
        sc.close();

        int[][] array = new int[multilist.size()][b];
        for (int i = 0; i < array.length; i++) {
            array[i] = new int[multilist.get(i).size()];
        }
        for (int i = 0; i < multilist.size(); i++) {
            for (int j = 0; j < multilist.get(i).size(); j++) {
                array[i][j] = multilist.get(i).get(j);
            }
        }

        System.out.println(Arrays.deepToString(array));

        int[][] full_array = new int[c][b];
        System.out.println(Arrays.deepToString(full_array));

        // copy elements from jagged to normal 2D array
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                full_array[i][j] = array[i][j];
            }
        }

        System.out.println(Arrays.deepToString(full_array));
    }
}


Output:

Get number of two parameters: cyclists and bicycles: 
4 4
cyclists: 4 bicycles: 4
2 1 2
1 1
2 3 4
3 2 3 4
Elements are: [1, 2]
Elements are: [1]
Elements are: [3, 4]
Elements are: [2, 3, 4]
[[1, 2], [1], [3, 4], [2, 3, 4]]
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
[[1, 2, 0, 0], [1, 0, 0, 0], [3, 4, 0, 0], [2, 3, 4, 0]]


Solution

  • When you want to write the values to the correct indices they represent, then you can't just do full_array[i][j] = array[i][j], because this ignores the value and just simply "fills" the array, because j just increments normally.
    What you actually need to do is use the value of array[i][j] as index specification:

    full_array[i][array[i][j] - 1] = array[i][j];
    

    Mind that you need to reduce 1, because your values start from "1", but array indices from "0".

    Now the output is like you expect it to be:

    [[1, 2, 0, 0], [1, 0, 0, 0], [0, 0, 3, 4], [0, 2, 3, 4]]


    Now to some minor code improvements.

    1. ArrayList<ArrayList<Integer>> multilist = new ArrayList<ArrayList<Integer>>(); should be refactored to List<List<Integer>> multilist = new ArrayList<>();, because should declare your types as open as they could be, but as narrow as they need to be. You need a List, but you actually don't care it they are an ArrayList or for example a LinkedList. Also read Java - declaring from Interface type instead of Class.

    2. This cast multilist.add((ArrayList<Integer>) integers) is not needed. You had to added because you (correctly) declared integers as List<Integer> instead of ArrayList<Integer>, but since we fixed that in "1." you don't need it anymore.

    3. for (int i = 0; i < multilist.size(); i++) {
          System.out.println("Elements are: " + multilist.get(i));
      }
      

      can be replace with an enhanced-for-loop:

      for (List<Integer> integers : multilist) {
          System.out.println("Elements are: " + integers);
      }