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