The goal is to create a dynamic 'sum' row in a 2d javascript array. Here's the starting point:
var m = [[1,2,3], [4,5,6]];
We can add a third row thus:
Object.defineProperty(m, 2, { get: () => m[0].map((e, i)=> e + m[1][i]) })
So now our array is
[[1,2,3], [4,5,6], [5,7,9]]
It works! Setting m[0][0]=10
and we get
[[10,2,3], [4,5,6], [14,7,9]]
which is exactly what I want. m.length = 3
as expected, so the sum row is being treated as part of the array. JSON.stringify
works as expected too. (I was a bit surprised it worked tbh).
My question is - is there a way of generating parts of a 2d array dependent on other parts without resorting to defineProperty
? Is this something to avoid?
(Note - in my original question I had done the above, then changed m[2]
to something else. The 'property' won over the array member, which lead to some confusion. This in itself may be a reason not to use the above method. Apolgies.)
It works! I was a bit surprised it worked tbh.
Yes. Arrays are just objects with a special .length
property, the indices are just normal properties. Which means you can make them setters if you want to.
Btw, you can improve on that by using this
in the getter instead of always referring to m
:
var thirdRowDescriptor = {
enumerable: true,
configurable: true,
get() {
return this[0].map((x, i) => x + this[1][i]);
}
};
Object.defineProperty(m, 2, thirdRowDescriptor);
// or use the same descriptor on any other arrays
Is there a better way of generating parts of a 2d array dependent on other parts without resorting to defineProperty?
No, a getter created using Object.defineProperty
seems to be exactly what you want. There are many other ways of dynamically generating arrays dependent on others, but none of them really makes it "part of" the outer array.
Is this something to avoid?
Possibly. I'm pretty sure it destroys performance of the outer array (to which you added the getter), as the engine cannot optimise the index access easily. However, if that's really just a two-column object to which you wanted to add one other column, this should not be a problem. Just don't do it on large arrays or arrays that are growing/shrinking dynamically. Maybe using a plain object (not an array) for the outer structure would be a better choice, if its structure is static anyway.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With