Javascript 如何展平嵌套的forEach?

Javascript 如何展平嵌套的forEach?,javascript,loops,Javascript,Loops,我有以下意见: schema: [{ fields: [{ name: 'name', type: 'text', col: 10, value: '' }, { name: 'description', type: 'text', col: 2, value: '' }] }, { fields: [{ name: 'password',

我有以下意见:

 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) {
  this.schema.forEach((formGroup, index) => {
    formGroup.fields.forEach(field => {
      if (field.name === name) field.value = value
    })
  })
},

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

当然可以,但它并没有真正的好处

您当前的数据结构要求您迭代数组中每个项的每个子项

如果只是嵌套的外观让您感到困扰,那么您可以分离这些函数

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

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

  this.schema.forEach(updateFormGroup)
}
也就是说,除了个人口味之外,这里没有什么真正的好处


也许更好的关注点是如何使用常量访问结构(如
Map
Set

)来降低这些嵌套操作的二次复杂度,您可以使用
进行循环、对象分解、
object.entries()

const obj={
模式:[{
字段:[{
姓名:'姓名',
键入:“文本”,
上校:10,
值:“”
}, {
名称:'说明',
键入:“文本”,
上校:2,
值:“”
}]
}, {
字段:[{
名称:“密码”,
键入:“文本”,
上校:8,
值:“”
}, {
名称:“确认密码”,
键入:“textarea”,
上校:4,
值:“”
}]
}],
updateField(名称、值){
for(让Object.entries(this.schema)的[key,{fields}]{
for(让对象项(字段)的[索引,{name:_name}]{
if(name==\u name)字段[索引].value=value;
}
}
}
}
对象更新字段(“名称”,123);

console.log(obj.schema[0]。字段[0])您可以使用reduce和spread操作符来组合阵列,然后在平面阵列上进行forEach:

updateField (name, value) {
  this.schema
    .reduce((memo, item) => [...memo, ...item.fields], [])
    .forEach(field => {
      if (field.name === name) field.value = value;
    });
}
我建议引入一种便于迭代字段的方法:

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
  }
}

是的,将匿名回调移到外部,声明一个命名函数。是否需要嵌套数组?在我看来,如果您将输入格式更改为具有单个
字段
数组,则更易于使用。(如果你不能改变它的来源,你能在开始使用它之前改变它吗?)。但是我认为由于它的大小,它不太适用于这个特定的用例。是的,这将更新原始数组中的值,同时保持原始数组的结构完整。这就是我理解问题的意图。但是,它可以很容易地修改为根本不改变原始数组,或者完全改变整个数组结构。一切都取决于期望的结果。真的吗?也许我错了,但我的JSFIDLE表明,在原始数组上没有任何更改,您缺少了名称和值的变量。这是一个调用的方法,传入了预期的名称和值。您的名称未定义,因此永远不会执行if条件来更新名称。请看我更新的fiddle:值得指出的是,尽管此解决方案解决了嵌套回调的问题,但就复杂性而言,它要严重得多。这里的时间复杂度实际上是立方的,因为
每次都是一个完整的数组迭代。这也意味着它使用了更多的内存,因为reduce中的每次迭代都会创建一个新数组。话虽如此,如果数据量小,再加上它看起来更实用,因此也更优雅,那就不会是一个真正的问题:)