Anastasia Dunbar Anastasia Dunbar - 3 months ago 9
Javascript Question

Read an array with an array in Javascript?

If

a=[[1,[],"f",3],[3,[4,"x"]]]
and
b=[1,1]
.

I want to read
a
by
b
like
a[1][1]
to get
[4,"x"]
. Note that
b
is an array which should only consist of integers.

You could also do
eval('a['+b.join('],['+']')
but requires the actual variable name as string and it's ugly.

Here are some of my functions:

Array.prototype.readByArray = function(a) {
var c = this;
for (var i = 0; i < a.length; i++) {
c = c[a[i]];
}
return c;
};
Array.prototype.emptyByArray = function(a) {
var c = this.readByArray(a);
c.splice(0, c.length);
};
Array.prototype.concateByArray = function(a, e) {
var c = this.readByArray(a);
for (var i = 0; i < e.length; i++) {
c.push(e[i]);
}
};
Array.prototype.setByArray = function(a, e) {
this.emptyByArray(a);
this.readByArray(a).push(e);
};


This could be useful for reading a nested array in an imperative way in this example:

Array.prototype.readByArray=function(a){var c=this;for(var i=0;i<a.length;i++){c=c[a[i]];}return c;};
var a = [1,2,3,[1,2,3,[{x: 3},"test"],4],"foo","bar"]; //Your array
var b = [0]; //Reading stack
var s = '[\n'; //Output
while(b[0]<a.length){
if(Array.isArray(a.readByArray(b))){
s+=' '.repeat(b.length)+'[\n';
b.push(-1);
}else{
s+=' '.repeat(b.length)+JSON.stringify(a.readByArray(b))+'\n';
}
b[b.length-1]++;
while(b[b.length-1]>=a.readByArray(b.slice(0,-1)).length){
b.pop();
b[b.length-1]++;
s+=' '.repeat(b.length)+']\n';
}
}
console.log(s);


Is there any better way to do this? Are there native functions for this?

Answer

You could use Array#reduce for it.

You start with the whole array and return for every element of b a part of the array until all indices are used.

var a = [[1, [], "f", 3], [3, [4, "x"]]],
    b = [1, 1],
    result = b.reduce(function (v, i) {
        return v[i];
    }, a);
    
console.log(result);

ES6

var a = [[1, [], "f", 3], [3, [4, "x"]]],
    b = [1, 1],
    result = b.reduce((v, i) => v[i], a);
    
console.log(result);
result[0] = 42;
console.log(result);