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 ?

but-why
  • 533
  • 3
  • 10
  • 1
    Hmm, it's hard to understand what you're going for. What's a dynamic selector? – Nick Dec 17 '20 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. – ggorlen Dec 17 '20 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. – but-why Dec 17 '20 at 14:27
  • 1
    Does this answer your question? [In javascript how can I dynamically get a nested property of an object](https://stackoverflow.com/questions/6906108/in-javascript-how-can-i-dynamically-get-a-nested-property-of-an-object) – ggorlen Dec 17 '20 at 14:28
  • I fail to see how your desired "selector" improves upon `obj.key_1.arr[1].key_3`. – daddygames Dec 17 '20 at 14:28
  • "Syntactically nice" is a bit of rock management. What are you trying to get out of it? – Nick Dec 17 '20 at 14:28
  • @ggorlen Actually it kinda answers my question but I was hoping for something that does not use any iteration. – but-why Dec 17 '20 at 14:31
  • 1
    See [`lodash.get`](https://stackoverflow.com/a/33899328/6243352) 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. – ggorlen Dec 17 '20 at 14:34

1 Answers1

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
Daniil Loban
  • 4,165
  • 1
  • 14
  • 20