我具有以下数据结构:
const test1 = {
hero: {
update() {
console.log('updated hero in object');
},
},
zombies: [
{
update() {
console.log('updated zombie 1 in array of objects');
},
},
{
update() {
console.log('updated zombie 2 in array of objects');
},
},
],
};
我可以通过以下方式手动运行功能:
test1.hero.update()
test1.zombies[0].update()
test1.zombies[1].update()
但是会有数百个僵尸,其他数组和单个对象。
我是否需要递归才能全部运行它们,或者可以使用filter
或reduce
?我有以下代码片段,但似乎无法使其运行这些功能。 KEY是update,而VALUE是update()的事实使我不知所措!
我之前做了作弊,只是将hero
本身放在一个数组中,然后使用Object.keys
和2个嵌套的forEach
很容易,但这似乎是一个很弱的解决方案>
// Code shows keys and values of everything, but cant't run update()
const iterate = obj => {
Object.keys(obj).forEach(key => {
console.log(`KEY: ${key}, VALUE: ${obj[key]}`);
if (typeof obj[key] === 'object') {
iterate(obj[key]);
}
});
};
iterate(test1);
答案 0 :(得分:2)
您可以使用Array.prototype.flatMap
来实现。这是一个示例:
const test1 = {
hero: {
update() {
console.log('updated hero in object');
},
},
zombies: [
{
update() {
console.log('updated zombie 1 in array of objects');
},
},
{
update() {
console.log('updated zombie 2 in array of objects');
},
},
],
};
Array.prototype.flatMap = function (lambda) {
return Array.prototype.concat.apply([], this.map(lambda));
};
const caller = (data) => {
Object.entries(data)
.flatMap((keyValueArray) => {
const [key, objOrArrayValue] = keyValueArray;
if (objOrArrayValue instanceof Array) {
return objOrArrayValue;
}
return [objOrArrayValue];
})
.forEach(obj => obj.update());
};
caller(test1);
PS:为了演示,我从here获得了flatMap
的实现
答案 1 :(得分:1)
这可以通过updateEntityArray()
函数(见下文)实现,该函数提供了一种通用的递归解决方案:
const test1 = {
hero: {
update() {
console.log('updated hero in object');
},
},
zombies: [
{
update() {
console.log('updated zombie 1 in array of objects');
},
},
{
update() {
console.log('updated zombie 2 in array of objects');
},
},
],
};
/* Generic function that recursively calls update() on items
in supplied entities */
const updateEntities = (entities) => {
/* Iterate values of supplied entities */
for(const entity of Object.values(entities)) {
/* If this entity has an update function defined then call it */
if(typeof entity.update === 'function') {
entity.update();
}
/* If this entity is iterable then recursively call updateEntities
where any updatable children of this entity will be up updated as
well */
if(typeof entity[Symbol.iterator] === 'function') {
updateEntities(entity);
}
}
}
updateEntities(test1);