The problem is, JS doesn't have multidimensional arrays in the way many other languages do! That's actually an array of arrays, which isn't the same thing as a two-dimensional array. (If you're coming from a C-like language, think of this as "int *two_dim_ar[1]
", not "int two_dim_ar[1][1]
")
If you need multidimensional array semantics (rectangular shape, full cloning) I recommend making an indexer function, like so:
const array_width = 1;
function indexFor(r, c) {
return r * array_width + c;
}
let two_dimensional_array =
[1,
2];
let array_clone = [...two_dimensional_array]
array_clone[indexFor(0, 0)] = 3;
console.log(two_dimensonal_array[indexFor(0, 0)]); // 3
You can also extend Array
to create yourself a multidimensional array class, using something like this:
const array_width = 1;
class TwoDimensionalArray extends Array {
indexFor(r, c) { return r * array_width + c }
get(r, c) { return this[this.indexFor(r, c)]; }
set(r, c, v) { return this[this.indexFor(r, c)] = v; }
delete(r, c) { delete this[this.indexFor(r, c)]; }
}
let two_dimensional_array = TwoDimensionalArray.of(
1,
2
);
// using [...tda] always creates a base Array, but .slice(0) maintains the species:
let array_clone = two_dimensional_array.slice(0);
array_clone.set(0, 0, 3);
console.log(two_dimensional_array.get(0, 0)); // 3
But of course, you probably want to be able to make arrays of different widths, and to be able to perform various operations on them while maintaining their widths, so make the array class a family of classes instead:
const TwoDimensionalArrayFactory = (array_width) => class extends Array {
// all code remains the same as above
};
let two_dimensional_array = TwoDimensionalArrayFactory(1).of(
1,
2
);
// all remaining code the same
You could obviously do something to translate the array-of-arrays into true multidimensional array form, but if you need that, the exercise is left to the reader
One potential pitfall to be aware of: the TwoDimensionalArrayFactory
above doesn't cache the dynamically created array classes, so instanceof
checks like this will fail:
const tda = TwoDimensionalArrayFactory(1).of(1, 2);
console.log(tda instanceof TwoDimensionalArrayFactory(1)); // false
instead, modify the factory to cache each width, or store the created class at the call site:
const Width1Array = TwoDimensionalArrayFactory(1);
const w1a = Width1Array.of(1, 2);
console.log(w1a instanceof Width1Array); // true