Alexandre Wiechers Vaz
Alexandre Wiechers Vaz

Reputation: 1617

Making matrices in dart

Ok guys, i've tried this:

List<num> test
for(num i = ...){
   test[i]...
   (...)
    for(num j = ...){
      test[i][j] = ...
    }
}

today but didn't seem to work. My question is... Is there a way to make this in Dart? :)

Upvotes: 3

Views: 10905

Answers (3)

Seth Ladd
Seth Ladd

Reputation: 120619

Here is one way to do it:

main() {
  List<List<int>> matrix = new List<List<int>>();
  for (var i = 0; i < 10; i++) {
    List<int> list = new List<int>();

    for (var j = 0; j < 10; j++) {
      list.add(j);
    }

    matrix.add(list);
  }

  print(matrix);
  print(matrix[2][4]);
}

If you know the length ahead of time, and it won't change, you can pass the length to the constructor:

main() {
  int size = 10;
  List<List<int>> matrix = new List<List<int>>(size);
  for (var i = 0; i < size; i++) {
    List<int> list = new List<int>(size);

    for (var j = 0; j < size; j++) {
      list[j] = j;
    }

    matrix[i] = list;
  }

  print(matrix);
  print(matrix[2][4]);
}

Notice the main difference. In the first example, the list is created empty, so the loops need to explicitly add elements to the list. In the second example, the list is created with a fixed size, with null elements at each index.

Changelog: The original version of the second example used the List.fixedLength(size) constructor, which existed before Dart 1.0.

Upvotes: 8

scribeGriff
scribeGriff

Reputation: 637

There are some excellent libraries on pub for handling matrices (like Kevin Moore's BOT for example), but if your looking for something quick, you can just do:

List<List> test = new List<List>(n);
for (var i = 0; i < n; i++) {
  test[i] = new List(n);
}

for (var i = 0; i < n; i++) {
  for (var j = 0; j < n; j++) {
    test[i][j] = myValue;
  }
}

Upvotes: 1

Stephen
Stephen

Reputation: 471

One way to construct a list with a different value in each position is to use the idiom new Iterable.generate(size, function).toList()

makeMatrix(rows, cols) =>
    new Iterable<List<num>>.generate(
        rows,
        (i) => new List<num>.fixedLength(cols, fill: 0)
      ).toList();

main() {
  print(makeMatrix(3, 5));
}

prints: [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

It is slightly annoying that to get the fill: parameter you have to construct a fixed length list. Without a fill value, the inner lists would contain nulls. One way to get an extendable list with an initial value is to create an empty list and grow it.

(i) => <num>[]..insertRange(0, cols, 0)

This is using a method cascade to modify the list before returning it - a..b()..c() calls a.b() and a.c() before returning a. This is handy as it avoids the need for a temporary variable. Note that, for some reason, insertRange has a positional rather than a named fill parameter.

If you want more control over the contents, you can extend the generate-to-list idea to two levels:

makeMatrix(rows, cols, function) =>
    new Iterable<List<num>>.generate(
        rows,
        (i) => new Iterable<num>.generate(cols, (j) => function(i, j)).toList()
      ).toList();

main() {
  print(makeMatrix(3,5, (i, j) => i == j ? 1 : 0));
}

prints: [[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0]]

Upvotes: 3

Related Questions