2

If there is a Javascript object with multiple levels, as in:

myObject = {
        a: 12,
        obj11: {
                obj111: 'John',
                b:13,
                obj1111: { a:15, b: 35 } 
        },
        obj21: { 
                a:15,
                b:16 }
        }

I want to write a function to which is passed the object and an array of keys. The function should return a value based upon these keys. For example, passing [obj11,b] should return 13. Passing [obj11, obj1111,a] should return 15. Passing obj21 should return the object {a:15, b:16}

  function (myObj,myArr) {

      return keyVal;
  }

Assuming that the keys are always correct, can anyone help me solve this problem?

1
  • Does the format of the selector matter?.. eg. would obj11.b work? Commented Oct 28, 2017 at 20:26

3 Answers 3

3

You could reduce the array with the keys and take an object as default value.

function getValue(object, path) {
    return path.reduce(function (r, k) {
        return (r || {})[k];
    }, object);
}

var object = { a: 12, obj11: { obj111: 'John', b: 13, obj1111: { a: 15, b: 35 }, obj21: { a: 15, b: 16 } } };

console.log(getValue(object, ['obj11', 'b']));
console.log(getValue(object, ['obj11', 'obj1111', 'a']));
console.log(getValue(object, ['obj11', 'obj21']));
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

4 Comments

Amazing! Thanks. I need to take a look at reduce. Can you save me some time to also have a setValue function.
it's just the reverse function with taking the obejct and build an object if not set, at last assign the value.
I tried but I could not get it. The third argument to the function is the new value to be assigned. It is not exactly reverse of this function, I think.
3

You can do this with a reduce() one-liner. Of course if you want to wrap it in a function, you can do that too.

var myObject = {
    a: 12,
   obj11: {
           obj111: 'John',
           b:13,
           obj1111: { a:15,
                      b: 35 }
           },
   obj21: {
           a:15,
           b:16 }
}

var arr =   ['obj11','b']
var val = arr.reduce((acc,curr) => acc[curr], myObject)
console.log(val)

var arr =   ['obj11','obj1111', 'b']
var val = arr.reduce((acc,curr) => acc[curr], myObject)
console.log(val)

3 Comments

['obj11','obj1111', 'b', 'a', 'a'] will throw Error, returning undefined might be nicer.
Yup - I totally agree @Keith
@Mark_M Please see if you can help me with this one. Sounded simple when I read on reduce but am stuck.
0

To increment the discussion, if you're using lodash you can also use the function _.get to get the value like this:

_.get(myObject, ['obj111', 'obj1111'])
//returns 'John'

If you object has properties with array values you can also get by indexes

var obj = {
        a: 1,
        b:[{
           d:4,
           c:8
        }]

_.get(obj, ['b','0','d'])
//returns 4

Source: https://lodash.com/docs/4.17.4#get

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.