[英]Recursively find keys on an object
我有一个这样的javascript对象;
brand: {
group: {
subGroup: {
items: []
},
otherSub: {
items: []
}
}
}
给定一系列键['brand','group','newGroup','newSubGroup'],我想将这些键分为找到的和丢失的键。 因此,对于上面的结构,我应该回来;
present = ['brand', 'group']
missing = ['newGroup', 'newSubGroup']
我正在使用ES6并具有可用的lodash,但正在努力寻找一种干净的方法来实现这一点。
这不仅是检查存在性,而是递归地找到键并返回存在的键和剩余的键。
这是一种相当粗略的方法。
const find = (keys, obj) => { const string = JSON.stringify(obj); return keys.reduce(({ present, missing }, key) => { const match = string.match(new RegExp(`"${key}":`)); if (match) { present.push(key); } else { missing.push(key); } return { present, missing }; }, { present: [], missing: [] }); }
您可以使用为您量身定制的此功能;)
var getAttrs = function(obj) {
return [].concat.apply([], Object.keys(obj).map(function (key) {
var results = [key]
if (typeof obj[key] === 'object') {
Array.prototype.push.apply(results, getAttrs(obj[key]))
}
return results
}))
}
它返回属性和子属性的列表。
getAttrs({brand: {
group: {
subGroup: {
items: []
},
otherSub: {
items: []
}
}
}})
> ["brand", "group", "subGroup", "items", "otherSub", "items"]
您可以像这样使用它:
var lookingFor = ['brand', 'group', 'newGroup', 'newSubGroup']
var existings = getAttrs(obj)
var missings = []
var presents = []
lookingFor.forEach(attr => {
if (existings.indexOf(attr) === -1) {
missings.push(attr)
} else {
presents.push(attr)
}
})
var toFind = ['brand', 'group', 'newGroup', 'newSubGroup'], found = []; var o = { brand: { group: { subGroup: { items: [] }, otherSub: { items: [] } } } } //called with every property and its value function process(key,value) { var i = toFind.indexOf(key); if(i !== -1){ found.push(key); toFind.splice(i, 1); } } function traverse(o,func) { if(!toFind.length) return; for (var i in o) { func.apply(this,[i,o[i]]); if (o[i] !== null && typeof(o[i])=="object") { //going one step down in the object tree!! traverse(o[i],func); } } } traverse(o,process); console.log(found); // present console.log(toFind); // absent
我编写了一个函数以从嵌套对象中递归地获取唯一键,然后过滤了您提到的所有键的数组,这些键检查了函数结果中是否存在。
var thisObject = { brand: { group: { subGroup: { items: [] }, otherSub: { items: [] } } } }; var arr_full = ['brand', 'group', 'newGroup', 'newSubGroup'] ; var key_array = []; function addToKeyArray( key_array, object ){ for( var key in object ){ // only get unique keys if( key_array.indexOf( key ) === -1 ){ key_array.push( key ); } // concat the result of calling this function recurrsively on object[key] key_array.concat( addToKeyArray( key_array, object[key] ) ); } return key_array; } var test = addToKeyArray( [], thisObject ); var missing = arr_full.filter( function( el ) { return test.indexOf( el ) < 0; }); console.log( test ); console.log( missing )
您可以在另一个函数内使用for...in
循环创建递归函数for...in
并返回对象作为结果。
var obj = {"brand":{"group":{"subGroup":{"items":[]},"otherSub":{"items":[]}}}} var keys = ['brand', 'group', 'newGroup', 'newSubGroup'] ; function findKeys(data, keys) { keys = keys.slice(); function findPresent(data, keys) { var result = [] for(var i in data) { if(typeof data[i] == 'object') result.push(...findPresent(data[i], keys)) var index = keys.indexOf(i); if(index != -1) result.push(...keys.splice(index, 1)) } return result } return {present: findPresent(data, keys), missing: keys} } console.log(findKeys(obj, keys))
为了保持内容整洁易读,您可以在嵌套函数内使用“ for in”进行递归。
function recur(obj) { let preMiss = { present: [], missing: [] } let root = traverse => { for (let key in traverse) { if (Array.isArray(traverse[key].items)) { preMiss.missing.push(key); } if (typeof traverse[key] === 'object' && !Array.isArray(traverse[key].items)) { preMiss.present.push(key); root(traverse[key]) } } } root(obj); return preMiss; } const object = { brand: { group: { subGroup: { items: [] }, otherSub: { items: [] } } } } console.log(Object.entries(recur(object)));
即使这个问题有点老了,我还是想提出一个解决这个问题的简短方法。
const recursivelyGetKeys = obj => Object.keys(obj).map(key => typeof obj[key] === 'object'
? [...recursivelyGetKeys(obj[key]), key] : [key]).reduce((p, c) => [...p, ...c], [])
此函数将返回对象中的所有键,因此使用以下命令调用数组arr
const arr = {
brand: {
group: {
subGroup: {
items: []
},
otherSub: {
items: []
}
}
}
}
将输出:
const keys = recursivelyGetKeys(arr) // = ["items", "subGroup", "items", "otherSub", "group", "brand"]
现在,找到它的交集并find = ['brand', 'group', 'newGroup', 'newSubGroup']
,执行以下操作:
const found = keys.filter(key => find.some(val === key))
const missing = keys.filter(key => find.every(val !== key))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.