snippetjavascriptTip
Creating a Matrix data structure in JavaScript
Viewed 0 times
javascriptdatamatrixstructurecreating
Problem
It's no secret I've been solving a lot of algorithmic problems lately. Many of them involve dynamic programming and 2D arrays. Unlike other languages, JavaScript's syntax isn't very convenient for working with 2D arrays, or as math people call them, matrices. So, I took matters into my own hands and created a class that contains most of the functionality I need.
> [!NOTE]
>
> This implementation is by no means complete. It's a relatively extensive solution that covers a lot of different needs and gives you the basic building blocks. Feel free to extend it to your liking.
After fooling around with 1D and 2D arrays, it turns out that the naive approach of a 2D array is the most efficient, given how it affects the performance of operations. On top of the
> [!NOTE]
>
> This implementation is by no means complete. It's a relatively extensive solution that covers a lot of different needs and gives you the basic building blocks. Feel free to extend it to your liking.
After fooling around with 1D and 2D arrays, it turns out that the naive approach of a 2D array is the most efficient, given how it affects the performance of operations. On top of the
data 2D array, we'll also keep track of the number of rows (rows) and columns (cols). This will help us avoid unnecessary calculations when we need to access the dimensions of the matrix.Solution
const matrix = new Matrix([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]);
// Matrix {
// rows: 3, cols: 3,
// data: [
// [ 1, 2, 3 ],
// [ 4, 5, 6 ],
// [ 7, 8, 9 ]
// ]
// }>
> This implementation is by no means complete. It's a relatively extensive solution that covers a lot of different needs and gives you the basic building blocks. Feel free to extend it to your liking.
After fooling around with 1D and 2D arrays, it turns out that the naive approach of a 2D array is the most efficient, given how it affects the performance of operations. On top of the
data 2D array, we'll also keep track of the number of rows (rows) and columns (cols). This will help us avoid unnecessary calculations when we need to access the dimensions of the matrix.Before we can initialize the data in the matrix, we'll need some methods to help us with that. I'm going to add the following for starters:
fill: Fills the matrix with a specific value.copy: Creates a deep copy of the matrix.
Code Snippets
const matrix = new Matrix([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]);
// Matrix {
// rows: 3, cols: 3,
// data: [
// [ 1, 2, 3 ],
// [ 4, 5, 6 ],
// [ 7, 8, 9 ]
// ]
// }class Matrix {
constructor(data) {
if (Array.isArray(data)) {
this.rows = data.length;
this.cols = data[0].length;
this.data = data;
} else {
this.rows = data.rows;
this.cols = data.cols;
this.fill(0);
}
}
static from({ rows, cols }) {
return new Matrix({ rows, cols });
}
static zeroes({ rows, cols }) {
return new Matrix({ rows, cols });
}
static identity({ size }) {
return new Matrix(
Array.from({ length: size }, (_, i) =>
Array.from({ length: size }, (_, j) => (i === j ? 1 : 0))
)
);
}
fill(value) {
this.data = Array.from({ length: this.rows }, () =>
Array.from({ length: this.cols }, () => value)
);
}
copy() {
return new Matrix(this.data.map(row => row.map(value => value)));
}
}class Matrix {
*indexes() {
for (let i = 0; i < this.rows; i++)
for (let j = 0; j < this.cols; j++) yield [i, j];
}
*values() {
yield* this[Symbol.iterator]();
}
*entries() {
for (let [i, j] of this.indexes()) yield [i, j, this.data[i][j]];
}
*[Symbol.iterator]() {
for (let [i, j] of this.indexes()) yield this.data[i][j];
}
}Context
From 30-seconds-of-code: matrix-data-structure
Revisions (0)
No revisions yet.