简体   繁体   English

如何根据 javascript 中的数组中的路径遍历嵌套的 object?

[英]How to traverse a nested object based on a path in an array in javascript?

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.给定第一个输入为嵌套的 object,第二个输入为包含字符串的数组。 What is the best way to traverse the nested object based on the path set by the array to output 'done'?根据数组设置为 output 'done' 的路径遍历嵌套 object 的最佳方法是什么?

You can reduce the array arr , changing the accumulator to a deeper object at each step.您可以reduce数组arr ,在每一步将累加器更改为更深的 object 。

 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']));

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]如果ref[key]是 object,请将ref更改为ref[key]
  • else return Not Found否则返回Not Found
  • Check if the ref has property name same as last variable then return ref[last] else return Not Found检查ref的属性名称是否与last变量相同,然后返回ref[last]否则返回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']))

if you want it short and to handle system file path like:如果您希望它简短并处理系统文件路径,例如:

it returns the object if exist and -1 if not如果存在则返回 object,如果不存在则返回 -1

 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() :甚至用reduce()而不是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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM