How to index a matrix to get a subset of rows and/or columns?

I would like to access a subset of rows and/or columns of a 2D matrix:

let matrix : [[Nat]] = [[1,2,3],
                        [4,5,6],
                        [7,8,9],];

How can I get a set of rows (e.g. row 1 and row 2). The code below does not work:

let rows: [Int] = [0,1];
aux = matrix[rows]

Is that possible at all? should I create my own matrix class?

There’s not built-in syntactic support for this, so you’ll need to write code for this. For rows, it should be easy, for columns a little harder.

In Motoko, the indexing notation is just for that: indexing. No slicing and dicing, I’m afraid.

About the design strategy, is there ways to override operators like [] or should I create new functions in a new module “matrix”? In your opinion, the base type for “matrix” should be “Array” or just
“vec”?

There’s no overriding of [].
I would just create new functions in a module.
There’s no vec type in Motoko, so I don’t understand that question.
You do have a choice of using row-major or column-major nested or unnested arrays (where you do the index translation yourself).

To get back to the original question of how to define rows/cols functions. Here’s one way (for this representation). Note it does no error-checking so will trap, e.g. if the matrix rows are too short.

import Array "mo:base/Array";

actor {

  func rows<T>(rs : [Nat], m : [[T]]) : [[T]] {
    Array.tabulate<[T]>(rs.size(), func r { m[rs[r]] });
  };

  func cols<T>(cs : [Nat], m : [[T]]) : [[T]] {
    Array.tabulate<[T]>(m.size(), func r {
       Array.tabulate<T>(cs.size(), func c { m[r][cs[c]] }) });
  };

  public func test() : async () {
    let matrix : [[Nat]] = [
      [1, 2, 3],
      [4, 5, 6],
      [7, 8, 9],
    ];
    assert (
      rows([0, 2], matrix) == [
        [1, 2, 3],
        [7, 8, 9],
      ]
    );
    assert (
      cols([0, 2], matrix) == [
        [1, 3],
        [4, 6],
        [7, 9],
      ]
    );

  };
};
1 Like