简体   繁体   English

如何迭代对象中的对象和对象数组,并在每个对象中运行相同的函数?

[英]How can I iterate over objects and arrays of objects in an object and run the same function in each object?

I have the following data structure: 我有以下数据结构:

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

I can manually run the functions with: 我可以手动运行这些功能:

test1.hero.update()
test1.zombies[0].update()
test1.zombies[1].update()

But there will be hundreds of zombies, and other arrays and single objects. 但是会有数百个僵尸,以及其他数组和单个对象。

Do I need recursion to run them all, or maybe filter or reduce could be used? 我是否需要递归来运行它们,或者可能使用filterreduce I have the following code snippet, but I can't seem to make it run the functions. 我有以下代码片段,但我似乎无法让它运行函数。 The fact the KEY is update and the VALUE is update() is throwing me somehow! KEY更新而VALUE是update()的事实让我不知何故!

I did cheat before and just put the hero in an array by itself and then it is easy using Object.keys and 2x nested forEach s, but it seems a weak solution 我之前做过欺骗,只是将hero放在一个数组中,然后使用Object.keys和2x嵌套forEach很容易,但它似乎是一个弱解决方案

// Code shows keys and values of everything, but can'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);

You can use Array.prototype.flatMap to achieve this. 您可以使用Array.prototype.flatMap来实现此目的。 Here is an example: 这是一个例子:

 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: for demostration, I obtained the flatMap implementation from here PS:为了演示,我从这里获得了flatMap实现

This could be achieved via the updateEntityArray() function (see below) which provides a generic, recursive solution: 这可以通过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); 

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

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