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

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.