3

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?

3
  • 1
    Protip: Don't change Array's prototype. It will give you more headaches than usefulness. Commented Aug 20, 2016 at 16:26
  • @Derek朕會功夫 Give me some examples. Commented Aug 20, 2016 at 16:28
  • 1
    Why is extending native objects a bad practice? Many libraries in the last decade have tried to modify builtin object's prototype, and they all failed miserably. The general principle is that you only change what you own, and leave objects that you don't own untouched. Commented Aug 20, 2016 at 16:35

2 Answers 2

3

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(a);
result.splice(0, result.length, 'test');
console.log(a);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

5 Comments

With ES6, you are able to make it neater with const result = b.reduce((v, i) => v[i], a)
Thank you, can I change the element inside of [4,"x"]?
yes, you can, because you get the reference to the array. please see second example.
If I had to like set that array into an another element as result=["test"] how would I do that?
you could use Array#splice, for keeping the reference and delete all elements inside and move the new content to the reference. please see edit in the second example.
0

I had written a reusable generic code exactly for this purpose to get the nested object properties dynamically. Actually i was targeting objects but since in JS an array is a perfect object it also applies for arrays too. So lets see how it works in this particular case;

Object.prototype.getNestedValue = function(...a) {
  return a.length > 1 ? (this[a[0]] !== void 0 && this[a[0]].getNestedValue(...a.slice(1))) : this[a[0]];
};

var a = [[1,[],"f",3],[3,[4,"x"]]],
    b = [1,1],
    c = a.getNestedValue(...b);
console.log(c)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.