HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptTip

Creating a Matrix data structure in JavaScript

Submitted by: @import:30-seconds-of-code··
0
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 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.