0

Suppose I have this javascript object:

var obj = {
    key_1: {
        arr: [
            999,
            {
                key_3: 5
            }
        ]
    },
    key_2: 'value_2'
};

and I want to access the value 5.

What I would do is obj.key_1.arr[1].key_3.

But I want to have something like a json selector: ['key_1']['arr'][1]['key_3'] and dynamically apply it to the obj.
But I have no clue how to efficiently hold in a variable such a selector. Also, I would like to have the ability to "concat" such selectors. For example:

// pseudocode

s1 = ['key_1']['arr'];
s2 = [1]['key_3'];
s = s1 + s2;
v = obj[s];
// v === 5

Is there a nice way to do something like this in javascript ?

8
  • 1
    Hmm, it's hard to understand what you're going for. What's a dynamic selector? Commented Dec 17, 2020 at 14:24
  • 1
    To be pedantic, JSON has nothing to do with this and I'm not sure how bracket object access qualifies as a "JSON selector". If you want this to be dynamic, simply replace the hardcoded strings with variables: ['key_3'] -> [foo]. If you're not sure how deep the selector goes, then you'll need to key/index in step by step using a loop--you can't dynamically concat up a bunch of these and key into multiple levels deep in one step. Secondly, this seems like an XY problem. What is this supposed to accomplish? There might be a better way to achieve whatever you mean to achieve here. Commented Dec 17, 2020 at 14:24
  • @Nick Dynamic might be a confusing term. I mean having the selector in a variable (with some certain structure ?) in order to apply it to the object and access the value. But, for example, I don't want to have something like a list: ['key_1', 'arr', 1, 'key_3' and create a function that iterates the list and access one by one the properties of the object. I would like something more syntactically nice. Commented Dec 17, 2020 at 14:27
  • 1
    Does this answer your question? In javascript how can I dynamically get a nested property of an object Commented Dec 17, 2020 at 14:28
  • 1
    See lodash.get in the other thread, but this introduces a dependency and lodash uses a loop under the hood, so there's no way to do it without a loop. Commented Dec 17, 2020 at 14:34

1 Answer 1

1

Solution for similar task

function getDepthValue(obj, path, defaultValue) {
  let props;
  if (typeof obj === "undefined") return defaultValue;
  if (typeof path  === "string") {
    props = path.split(".").reverse();
  } else {
    props = path;
  } 
  if (path.length === 0) return obj || defaultValue;
  let current = props.pop();
  return getDepthValue(obj[current], props, defaultValue);
}

const obj = { 
  a: { 
    b: { 
      c: 'd' 
    },
    e: 'f'
  }
};

console.log(getDepthValue(obj, 'a.b'));   // { c : 'd' }
console.log(getDepthValue(obj, 'a.b.c')); // 'd'
console.log(getDepthValue(obj, 'a.e'));   // 'f'
console.log(getDepthValue(obj, 'a.x.e')); // undefined
console.log(getDepthValue(obj, 'a.x.e', true)); // true
console.log(getDepthValue(obj, 'a.x.e', 'My default value')); // My default value

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

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.