javascript - javascript按部分路径过滤对象

如何过滤给定的部分路径的对象?

作为一个例子。


let address = {


 country :{


 name:'Japan',


 city:{


 name:'Tokyo',


 town: {


 name:'korushawa'


 }


 },


 code:'JP'


 },


 nearbyCountry:'Korea'


}



path1:countr.cit

对于 address将导致


{


 country :{


 name:'Japan',


 city:{


 name:'Tokyo',


 town: {


 name:'korushawa'


 }


 }


 }


}



path2: 国家

对于 10gen,我应该得到整个 address 对象,因为国家/地区是在和 nearbyCountry


{


 country :{


 name:'Japan',


 city:{


 name:'Tokyo',


 town: {


 name:'korushawa'


 }


 }


 },


 nearbyCountry:'Korea'


}



编辑:我能够在给定确切路径的情况下解决这个问题( 例如: country.city ) 但在部分路径中存在困难。

时间:

  • 你可以创建一个递归函数,该函数接受一个对象和部分路径的array 作为参数。
  • 获取最新的部分路径,并且 filterinclude 加载到路径中
  • 如果没有键,则返回 null
  • 否则,使用 reduce 从键创建一个对象
    • 如果没有剩余的键,只需将 obj的所有过滤特性添加到累加器
    • 否则,递归调用函数获取另一个嵌套对象

const address={country:{name:'Japan',city:{name:'Tokyo',town:{name:'korushawa'}},code:'JP'},nearbyCountry:'Korea'};



function filterObject(obj, paths) {


 if (!obj) return null;



 const partial = paths.shift(),


 filteredKeys = Object.keys(obj).filter(k => k.toLowerCase().includes(partial));



 if (!filteredKeys.length) return null;//no keys with the path found



 return filteredKeys.reduce((acc, key) => {


 if(!paths.length) return {.. .acc, [key]: obj[key] }



 const nest = filterObject(obj[key], [...paths])//filter another level


 return nest? {.. .acc, [key]: nest } : acc


 }, null)


}



let path;


console.log(path = 'countr', ':');


console.log(filterObject(address, path.split('.')))



console.log(path = 'countr.cit', ':');


console.log(filterObject(address, path.split('.')))



console.log(path = 'countr.cit.to', ':');


console.log(filterObject(address, path.split('.')))



console.log(path = 'countr.cit.doesntexist', ':');


console.log(filterObject(address, path.split('.')))
.as-console-wrapper {max-height:100%!important; top:0;}

如果你只需要完全或者部分匹配键,就可以拆分 path 并使用 reduce,。 如果找到键,返回对象,或者找到给定键的键( 这给出最后一个键匹配的数据) 。 不是整个对象树)


const address={country:{name:'Japan',city:{name:'Tokyo',town:{name:'korushawa'}},code:'JP'},nearbyCountry:'Korea'},


 path ="countr.cit";



const output = path.split('.').reduce((obj, key) => {


 if (key in obj) {


 return obj[key];


 } else {


 let found = Object.keys(obj).find(k => k.includes(key));


 if (found)


 return obj[found]


 else


 return {}


 }


}, address);



console.log(output)

对于question的问题是,OP希望返回部分路径为的第三级值,它是使用递归的代码。


const address={country:{name:'Japan',city:{name:'Tokyo',town:{name:'korushawa'}},code:'JP'},nearbyCountry:'Korea'}



function validPath(obj,path){


//checks if the path length is over path is ended so return true


 if(!path.length) return true;



//loop through the keys of obj


 for(let key in obj){



//check if keys matches with first element of path


 if(new RegExp(`${path[0]}`,"i").test(key)){



//call the function recursively by removing the first element of path. Which is already checked.



 let check = validPath(obj[key],path.slice(1));



//if path is valid for nested objects then return true


 if(check) return true;


 }


 }



//If none of keys are valid for path then return 'false'. (You can remove this like because it will then return 'undefined' which is also falsy)


 return false;


}


function getPart(obj,path){


//convert the given string to array


 path = path.split('.');



 return Object.fromEntries(


 Object.entries(obj)


//filtering the keys for which the 'first' element of 'path' matches and all the other nested path.


. filter(x => new RegExp(`${path[0]}`,"i").test(x[0]) 


 && validPath(x[1],path.slice(1)))


 )


}


let res = getPart(address,'countr.cit')


let res2 = getPart(address,'countr')



console.log(`For"countr.cit"`)


console.log(res)



console.log(`For"countr"`)


console.log(res2)
...