1

I have this object:

var object =  {item : {id : "51524512541"}};

Some service is passing this string:

var str = "item.id";

And I want to extract the id (51524512541).

Splitting by . (dot) is an option, but the object may be very deep.

Can maybe eval with try catch can help here somehow?

Luca Kiebel
  • 9,790
  • 7
  • 29
  • 44
SexyMF
  • 10,657
  • 33
  • 102
  • 206
  • try `_.get` https://lodash.com/docs/4.17.10#get – marzelin Sep 12 '18 at 14:18
  • If the objects are very deeply nested and strangely keyed, or with arrays in the mix, a normalized solution might be in order. Like lodash's `get` or one of the solutions offered [here](https://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key). – Roope Sep 12 '18 at 14:18
  • @marzelin jinx! – Roope Sep 12 '18 at 14:19
  • Possible duplicate of [Accessing nested JavaScript objects with string key](https://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key) – FK82 Sep 12 '18 at 15:15

2 Answers2

3

You can use reduce for this - go through array of indices and dive deeper into the object:

str.split('.').reduce((a, i) => a[i], object)

Explanation:

First, str is split into array, forming:

['item', 'id'].reduce((a, i) => a[i], object)

So You have array of indices, that You want to "visit". Now You call reduce on it - it takes the indices one by one and calls a function on every one of them (the i) and result of previous call (the a) and returns a[i], so it "dives" one level deeper in the object. The first call has no "previous result" available yet, so it takes the object as initial value.

So the real calls look like this:

i = 'item', a = {"item":{"id":123}} -> result a[i] is {"id":123}
i = 'id', a = {"id":123} -> result a[i] is 123
Roman Hocke
  • 4,137
  • 1
  • 20
  • 34
1

You could break the string up using split:

var splitStr = str.split('.')

Then use reduce to dive into the object.

const reducer = (accumulator, index) => accumulator ? accumulator[index] : accumulator
splitStr.reduce(reducer, object)

This should give you the result.

Check out more on reducers here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

Alternative option, which is probably more efficient:

let result = object
for(let str of splitStr) {
  if(!result) break;
  result = result[str]
}

Here's a JS Fiddle:

http://jsfiddle.net/h75dxsrz/15/

Michael Curry
  • 991
  • 8
  • 20