How to make an infinitely indexable array
Arrays in JS have a fixed number of elements. If you try to get one that is not contained, you'll get undefined
:
const arr = [0, 2, 4, 6];
console.log(arr[5]); // undefined
But in some cases, it is useful to have an Array that can be indexed infinitely. A function would do better, but in some cases that would require significant refactorings to track down all usages. Fortunately, there is a stopgap solution.
Use an ES6 Proxy.
A proxy can programatically handle property access, and indexing an Array is one of such operations.
To create a Proxy for an Array that handles property accesses, use:
new Proxy(arr, {
get: (target, key) => {
...
}
})
The target
is the original Array, and the key
is the name of the property.
One thing to keep in mind is that even though indexing uses numbers, the key itself will be a string, and the get
trap handles all accesses, not just indexing. It is therefore essential to discriminate between the two cases.
This can be done using a RegExp that checks if the accessed property is all numeric: /-?\d+/
. If this matches, calculate the result, if not, then let it pass through.
The solution then:
const infArr = new Proxy(arr, {
get: (target, key) => {
if (/-?\d+/.test(key)) {
const index = Number(key);
return index * 2;
}else {
return target[key];
}
}
})
console.log(infArr[5]); // 10
console.log(infArr[50]); // 100
console.log(infArr[-5]); // -10
Keep in mind that it is not an infinite Array, for example, length
still returns the original number of elements. Also, it won't properly support map
, filter
and the other Array functions. The only thing that is supported is the indexing operation.
Therefore, I don't suggest to use it for anything else than a stopgap solution until you can refactor the Array to a function.