# 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