1
const obj = { 
    first: { second: { third: 'done'} },
    hello: { world: { foo: { bar: 'wrong' } } },
    second: { third: 'wrong'}
};

const arr = [ 'first', 'second', 'third' ];

function traverse(obj, arr) {
    
}
// output = 'done'

Given a first input as a nested object, and a second input as an array containing strings, what is the best way to traverse the nested object based on the path set by the array to output done?

1
  • Use get method provided by lodash. lodash.com/docs/#get Commented Oct 10, 2019 at 2:27

3 Answers 3

2

You can reduce the array arr, changing the accumulator to a deeper object at each step.

const obj = { 
  first: { second: { third: 'done'} },
  hello: { world: { foo: { bar: 'wrong' } } },
  second: { third: 'wrong'}
};
const arr = [ 'first', 'second', 'third' ];

function traverse(obj, arr) {
  return arr.reduce((acc, curr) => acc ? acc[curr] : undefined, obj);
}

console.log(traverse(obj, arr));
console.log(traverse(obj, ['hello', 'world', 'foo']));
console.log(traverse(obj, ['first', 'hello', 'world']));

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

Comments

0

You can use references

  • Loop over the array untill the last second last element
  • If the ref[key] is an object, change ref to ref[key]
  • else return Not Found
  • Check if the ref has property name same as last variable then return ref[last] else return Not Found

const obj = { first: { second: { third: 'done'} },hello: { world: { foo: { bar: 'wrong' } } },second: { third: 'wrong'}};
const arr = [ 'first', 'second', 'third' ];

function traverse(obj, arr) {
  let ref = obj
  let last = arr[arr.length-1]
  for(let i=0; i<arr.length-1; i++){
    let key = arr[i]
    if(typeof ref[key] === 'object'){
      ref = ref[key]
    } else{
      return "Not found"
    }
  }
  return ref.hasOwnProperty(last) ? ref[last] : "Not found"
}

console.log(traverse(obj,arr))
console.log(traverse(obj,['first','third']))
console.log(traverse(obj,['hello','world']))

Comments

0

if you want it short and to handle system file path like :

it returns the object if exist and -1 if not

const obj = { 
    first: { second: { third: 'done'} },
    hello: { world: { foo: { bar: 'wrong' } } },
    second: { third: 'wrong'}
};

function traverse(obj, path) {
    let seq = path.split('/').filter(x => x != '');
    seq.map( s => obj = !obj[s] ? -1 : obj[s] );
    return obj;
}
console.log(traverse(obj, '/hello/notexist/'));
console.log(traverse(obj, '/hello/world/'));

or even shorter with a reduce() instead of a map() :

function traverse(obj, path) {
    let seq = path.split('/').filter(x => x != '');
    return seq.reduce((acc, curr) => !acc[curr] ? -1 : acc[curr], obj);
}

or a even even shorter :

 function traverse(obj, path) {
      return path
      	.split('/')
        .filter(Boolean)
        .reduce((acc, curr) => acc[curr] ? acc[curr] : -1, obj);
}
    
const obj = { 
        first: { second: { third: 'done'} },
        hello: { world: { foo: { bar: 'wrong' } } },
        second: { third: 'wrong'}
};

const res = traverse(obj, '/hello/world/'); // return {foo:...}
console.log(res);

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.