javascript中的丑陋嵌套forEach最佳实践

时间:2018-09-30 20:35:06

标签: javascript foreach

嗨,我的代码感觉很hacky,我可以用forloop来做同样的事情,这会提高性能,但看起来会更可怕。有没有更清洁/最佳实践的方法?

这是我的数据模型

this.data = [
  {
    title: 'Math',
    img: this.mathImage,
    children: [
      {
        title: 'Calculus I & II',
        open: false,
        children: [
          {
            title: 'Differentials',
            open: false,
            children: [
              {
                title: 'Integration by parts',
                key: 'Differentials1',
                mainsub: 'Math',
                middlesub: 'Calculus I & II',
                lowsub: 'Differentials',
                saved: true // <--------------- HERE IS THE PROPERTY
              },
              {
                title: 'Integration by parts',
                key: 'Differentials2',
                mainsub: 'Math',
                middlesub: 'Calculus I & II',
                lowsub: 'Differentials',
                saved: true,
              },
            ]
          }
        ]
      }
    ]
  }
]

这是我的代码,将“ saved”属性设置为false

removeFromFavoritesinSubjects(item) {
  this.data.forEach(list => {
    if (list.title === item.mainsub) {
      list.children.forEach(subitem => {
        if (subitem.title === item.middlesub) {
          subitem.children.forEach(items => {
            if (items.title === item.lowsub) {
              items.children.forEach(i => {
                if (i.key === item.key) {
                  i.saved = false;
                }
              })
            }
          })
        }
      })
    }
  })
} 

3 个答案:

答案 0 :(得分:1)

我将假设您只想在最低级别(即在其他级别没有保存的属性)时将已保存的设置更改为false。

此答案使用for... of递归遍历数组。

function changeSaved(data, key, value) {

  // loop through every object in the array
  for(var element in data){

    // see if there is a children node
    if(element.children){

      // run this function recursively on the children array
      changeSaved(element.children);

    } else {

      // no children key, set the value
      element[key] = value;
    }

  }

}

您会这样称呼它:

changeSaved(data, 'saved', 'false');

答案 1 :(得分:0)

线性搜索数据结构的效率很低,如果您必须更频繁地执行此操作,则应该将对对象的直接引用存储在item中,或者使用允许通过键进行有效查找的数据结构(例如, Map

我将使用链式.find()调用来代替嵌套循环(使用for … of.forEach()更好),

removeFromFavoritesinSubjects(item) {
  const list = this.data.find(list => list.title === item.mainsub);
  if (!list) return;
  const subitem = list.children.find(subitem => subitem.title === item.middlesub);
  if (!subitem) return;
  const items = subitem.children.find(items => items.title === item.lowsub);
  if (!items) return;
  const i = items.children.find(i => i.key === item.key);
  if (!i) return;
  i.saved = false;
}

(假设数组中没有重复项,并且每个removeFromFavouritesInSubjects()调用最多设置一个.saved属性)。

答案 2 :(得分:0)

您可以利用递归和CREATE TABLE products ( item_id INT AUTO INCREMENT, product_name VARCHAR(100), price INT, stock_quantity INT ); 函数先对数据模型进行扁平化,然后轻松地对平面数据模型进行操作。

.reduce

对于使用// flattenArray helper function turns nested array into flat array function flattenArray (array) { return array.reduce((result, item) => result.concat([ item ], flattenArray(item.children || [])) , []); } // later in code { // ... removeFromFavoritesInSubjects ({ key }) { // Consider all children are alongside with each other // [..., { title: 'Calculus I & II', ... }, { title: 'Differentials', ... }, ...] flattenArray(this.data).forEach(item => { if (item.key === key) { item.saved = false; } }); } // ... } for..loop的情况也不必太担心性能。