Skip to content

Instantly share code, notes, and snippets.

@brookjordan
Last active October 30, 2018 05:15
Show Gist options
  • Save brookjordan/142c461268d5b1cb911d8190a4440660 to your computer and use it in GitHub Desktop.
Save brookjordan/142c461268d5b1cb911d8190a4440660 to your computer and use it in GitHub Desktop.
Create multi-dimensional array with a useful getter and setter

Usage

let arr = new dimArray([3, 3, 3], Array(3 * 3 * 3).fill(0).map((_, i) => i));

Properties

arr.dimensionCount //=> 3
arr.size           //=> 27
arr.values         //=> [ [ [0, 1, 2], [3, 4, 5], [6, 7, 8] ], [ [9, 10, 11], [12, 13, 14], [15, 16, 17] ], [ [18, 19, 20], [21, 22, 23], [24, 25, 26] ] ]
[...arr]           //=> [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 ]

Methods

arr.get(1, 0, 2)      //=> 10
arr.set(1, 0, 2, 27);
arr.get(1, 0, 2)      //=> 27

TODO

  • override array functions
    • map
    • find
    • some
    • keys => how
    • join => how?
    • every
    • slice
    • filter
    • forEach
    • includes
class dimArray {
#dims;
#values;
[Symbol.iterator]() {
return this.#values.values();
}
get size() {
return this.#dims.reduce((a, c) => a * c, 1);
}
get dimensionCount() {
return this.#dims.length;
}
get values() {
let ref;
let values = this.#values.slice(0);
this.#dims.forEach((dimSize, i) => {
if (i === this.#dims.length - 1) { return; }
ref = values;
values = [];
while (ref.length) {
values.push(ref.splice(0, dimSize));
}
});
return values;
}
set values(vals) {
if (!Array.isArray(vals)) {
throw Error(`The values variable should be of type 'array', not '${typeof vals}'.`);
}
if (vals.length !== this.size) {
throw Error(`Based on the dimensions, the value array should contain ${this.size} item${this.size === 1 ? '' : 's'}, not ${vals.length}.`);
}
this.#values = vals;
}
get(...args) {
return this.#values[this.getIndex(...args)];
}
set(...args) {
this.#values[this.getIndex(...args.slice(0, -1))] = args.pop();
}
getIndex(...args) {
if (args.length !== this.#dims.length) {
throw Error(`${args.length} arguments were passed to get but there are ${this.#dims.length} dimensions.`);
}
let index = 0;
let multiplier = 1;
args.slice(0).reverse().forEach((arg, i) => {
index += arg * multiplier;
multiplier *= this.#dims[i];
});
return index;
}
constructor(dimensionDistribution=[1], initialValues=[]) {
this.#dims = dimensionDistribution;
this.values = initialValues;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment