Working with multi-dimensional List in Dart
Hello and a very happy new year to everyone !
In today’s article we’ll take a look at another aspect of List
data type that can be used to create, manipulate and retrieve data represented in rows and columns (table format), or also called as matrix. We’ll see what is multi-dimensional List and how to create these Lists with examples of each, so let’s get started.
Simple vs multi-dimensional List
1D List or simply List
is a data type that has collection of data items in a linear fashion, mostly representing elements in a row with an index.
For instance, var intList = [1,2,3,4];
is the most basic declaration of a List datatype and we access it’s elements using single argument or index, as:
print(intList[0]); // 1
print(intList[1]); // 2
- Two-dimensional
Apart from single line of elements, there are many situations when given data is in table format, ie, along with row, we have to also consider column, making the data 2 dimensional.
For instance, below is a 3 x 3 table and each cell in the table is identified by a position using row and column index.
Here, if we want to access data of a particular cell, we would pass 2 arguments, one identifying row and other the column, as:
print(dList[0][0]);
print(dList[2][0]);
A 2D List data (eg: 3 x 3) in Dart can be represented like below:
[
[1, 1, 1],
[1, 1, 1],
[1, 1, 1]
]
which tells us that 2D List is nothing but a List of List, also known as nested List
.
- Three-dimensional
When it comes to multi-dimensional data, it is not only limited to 2D. The data can be in a 3D form as well, ie, along with row and column, it has one more parameter / dimension to it. For instance, a data in 3D form can look like below:
[
[[1, 2],[3, 4],[5, 6]],
[[7, 8],[9, 10],[11, 12]],
]
These data items [[1, 2],[3, 4],[5, 6]],[[7, 8],[9, 10],[11, 12]],
are in 2D form which are enclosed in main outer square brackets. So basically, we can say that 3D List is a List of 2D List.
Creating multi-dimensional List
Now since we have gone through the basics of what multi-dimensional List is, let’s see how to create one.
List
class provides a method named generate
, which generates a list of values and can be used to create a 2D and 3D list. The method definition is:
List<E>.generate(int length,E generator(int index), {bool growable: true})
length
indicates size of the list.generator
is a function that creates and fills values in the list for each index tilllength — 1.
growable
if false, creates fixed length list.
For instance, if we want to create a 2D list having 3 rows and 3 columns, we’ll do it as:
int a = 3;
int b = 3;
var tList = List.generate(a, (i) => List(b), growable: false);
print(tList); // [[null, null, null], [null, null, null], [null, null, null]]
Here, since we just instructed generator
to create a new List of size 3 without any value to work with, the List tList
is generated with default value ie null
.
As we learnt that a 2D list is a nested List, that means in order to create the data for column, we’ll need to call List.generate
method again that will create list of values based on the condition we provide in the inner generator
function. Let’s see an example:
var x = List.generate(3, (i) => List.generate(3, (j) => i + j));
print(x);// [[0, 1, 2], [1, 2, 3], [2, 3, 4]]
The index i starts from 0 till length
of the list and increments by 1 in next iteration generating values in the list as shown in the output.
If we want to create a 2D List with some default data, we can directly pass the list with said values, without making use of inner List.generate
, as below:
var dataList = List.generate(a, (i) => [0,0,0], growable: false);
print(dataList);// [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
The output can be simplified to represent in table form as:
[
[0, 0, 0],
[0, 0, 0],
[0, 0, 0]
]
Here, if we want to update a specific cell with new data, we’ll make use of the 2 arguments (row and column to identify the cell) followed with the data we want, as below:
dataList[0][2] = 5;
print(dataList);// [[0, 0, 5], [0, 0, 0], [0, 0, 0]]or[
[0, 0, 5],
[0, 0, 0],
[0, 0, 0]
]
While working on 2D list, if at any point of time we want to identify and retrieve size of dimensions, we can simply use the length
method, as below:
print(dataList.length); // 3
print(dataList[0].length); // 3
dataList.length
will retrieve size of the list which indicates that it’s a row, whereas, calling length
on index of the list will retrieve size of the column.
Similarly, we can also create a 3D List. Since 3D List is a List of 2D List, we’ll leverage the same syntax as we saw while creating 2D List, along with an outer List wrapped in 2D List. Let’s see an example:
var y = List.generate(
3, (i) => List.generate(3, (j) => List.generate(3, (k) => i + j + k)));
print(y);[[[0, 1, 2], [1, 2, 3], [2, 3, 4]], [[1, 2, 3], [2, 3, 4], [3, 4, 5]], [[2, 3, 4], [3, 4, 5], [4, 5, 6]]]
The inner-most List.generate
creates what we can call as the third dimesion or depth to the list. We can visualize this list as below:
Common use cases
Many a times, there could be a requirement to generate m x n matrix based on a condition such as, it should display random numbers, or display numbers in ascending or descending order. List.generate
method allows us to fulfil such conditions. Let’s take a look as how.
- A 3 x 3 matrix with 2 digit random numbers in it.
var rng = Random();
var m = 3;
var n = 3;
print(List.generate(m, (_) => List.generate(n, (_) => rng.nextInt(100))));// [[47, 25, 15], [23, 64, 43], [61, 29, 20]]
Here, we used the nested list concept and used Random
class, provided by dart core library, to generate non-negative integer number up to 100.
- A 4 x 4 matrix with ascending order numbers in it.
var ascList = List.generate(4, (i) => List.generate(4, (j) => i * 4 + j));
print(ascList);// [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]
Conclusion
List.generate
method comes very handy when we have requirements to create 2D or 3D List and also act upon the list using different methods to manipulate and retrieve data based on our need.