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?

4
  • try _.get lodash.com/docs/4.17.10#get Commented Sep 12, 2018 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. Commented Sep 12, 2018 at 14:18
  • @marzelin jinx! Commented Sep 12, 2018 at 14:19
  • Possible duplicate of Accessing nested JavaScript objects with string key Commented Sep 12, 2018 at 15:15

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

1 Comment

@Shazam: See @MichaelCurry's fiddle - res contains the result value (not object[res]).
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/

7 Comments

reduce would be more appropriate here since you convert array to something else
Yeah, you're completely right, never really touched a reducer before so this is a great example! I'll update my answer.
nice, but it fails with path x.y and an empty object {}. ;)
Something like (accumulator, index) => accumulator ? accumulator[index] : accumulator to fix this?
I'd use for...of. You can break from a loop early.
|

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.