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]]
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.
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.
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.
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);
}