如何展平嵌套的forEach?

时间:2017-05-16 02:02:54

标签: javascript loops

我有以下输入:

 schema: [{
    fields: [{
      name: 'name',
      type: 'text',
      col: 10,
      value: ''
    }, {
      name: 'description',
      type: 'text',
      col: 2,
      value: ''
    }]
  }, {
    fields: [{
      name: 'password',
      type: 'text',
      col: 8,
      value: ''
    }, {
      name: 'confirmPassword',
      type: 'textarea',
      col: 4,
      value: ''
    }]
  }],

我设置了嵌套数组的values对象:

updateField (name, value) {
  this.schema.forEach((formGroup, index) => {
    formGroup.fields.forEach(field => {
      if (field.name === name) field.value = value
    })
  })
},

有没有办法避免使用两个嵌套forEach? (不使用任何像Lodash这样的库?)

4 个答案:

答案 0 :(得分:3)

当然但它并没有带来任何好处。

您当前的数据结构是这样的,您需要遍历数组中每个项目的每个子项。

如果只有嵌套的外观困扰你,你可以将功能分开。

updateField (name, value) {
  const updateFormGroupField = field => {
     if (field.name === name) field.value = value;
  };

  const updateFormGroup = formGroup => formGroup.forEach(updateFormGroupField);

  this.schema.forEach(updateFormGroup)
}

话虽如此,除了个人风味之外,这里并没有任何好处。

或许更好的关注点是如何使用常量访问结构(如MapSet

来降低这些嵌套操作的二次复杂度

答案 1 :(得分:3)

您可以使用reduce和spread运算符展平数组,以组合您的数组,然后将每个数组合并到平面数组上:

updateField (name, value) {
  this.schema
    .reduce((memo, item) => [...memo, ...item.fields], [])
    .forEach(field => {
      if (field.name === name) field.value = value;
    });
}

答案 2 :(得分:1)

您可以使用for..of循环,对象解构,Object.entries()

const obj = {
  schema: [{
    fields: [{
      name: 'name',
      type: 'text',
      col: 10,
      value: ''
    }, {
      name: 'description',
      type: 'text',
      col: 2,
      value: ''
    }]
  }, {
    fields: [{
      name: 'password',
      type: 'text',
      col: 8,
      value: ''
    }, {
      name: 'confirmPassword',
      type: 'textarea',
      col: 4,
      value: ''
    }]
  }],
  updateField(name, value) {
    for (let [key, {fields}] of Object.entries(this.schema)) {
      for (let [index, {name: _name}] of Object.entries(fields)) {
        if (name === _name) fields[index].value = value;
      }
    }
  }
}

obj.updateField("name", 123);

console.log(obj.schema[0].fields[0]);

答案 3 :(得分:0)

我建议引入一个generator function来促进迭代字段:

function* fields(schema) {
  for (let group of schema) yield* group.fields;
}

function updateField(name, value) {
  for (let field of fields(schema)) {
    if (field.name === name) field.value = value
  }
}