代码之家  ›  专栏  ›  技术社区  ›  Mouad Ennaciri

JavaScript-改进递归循环,根据单个条件返回值

  •  1
  • Mouad Ennaciri  · 技术社区  · 6 年前

    group currentFilterName

    checkFilterValue(group, currentFilterName) {
      group.forEach((element, index) => {
        if (element.children) {
          if (element.name === currentFilterName) {
            this.returnedValue = element.value
          } else {
            this.checkFilterValue(element.children || this.filtersConfig[index + 1], currentFilterName)
          }
        } else {
          if (element.name === currentFilterName) {
            this.returnedValue = element.value
          }
        }
      })
    }
    

    深度级别是 element.children ,目标是返回 element.value ,如果元素具有深度级别,我首先检查 element.name === currentFilterName 如果是这样的话,我想把 元素值 this.filtersConfig [index + 1] ,如果元素没有深度,我只需检查 我又回到 元素值

    我的问题是这个方法有点冗长,我们如何用优雅的文字简化它?

    4 回复  |  直到 6 年前
        1
  •  1
  •   AnonymousSB    6 年前

    下面是如何递归地遍历数据以根据 filterName

    关于 forEach 你不能提早退出,但你可以 for 循环。你可以用 break; continue; 对于 循环以提前退出或跳过迭代。

    function checkFilterValue(data, filterName) {
      let result;
      const findValue = (data, filterName) => {
        for (let i = 0; i < data.length; ++i) {
          const current = data[i];
          if (current.name === filterName) {
            result = current.value;
            break;
          } else if (current.children) {
            findValue(current.children, filterName);
          }
        }
      }
      findValue(data, filterName);
      return result;
    }
    
    const data = [
      {
        name: 'a',
        value: 'b',
        children: [
          {
            name: 'c',
            value: 'd'
          }
        ]
      }
    ]
    
    console.log(checkFilterValue(data, 'c'));
        2
  •  1
  •   trincot Jakube    6 年前

    element.children || this.filtersConfig[index + 1] 价值 element.children 总是真实的,所以第二个表达式永远不会被计算。这意味着 this.filtersConfig 在算法中不起任何作用。

    下面是一个arrow函数,它将找到该值,但当它找到该值时,它也将停止与代码相反的迭代和递归:

    const checkFilterValue = (group, currentFilterName) =>
        group && group.some(element =>
            element.name === currentFilterName 
                ? (this.returnedValue = element.value, true) 
                : this.checkFilterValue(element.children, currentFilterName)
        );
    
        3
  •  1
  •   Vindicar    6 年前

    Array#some 所以你可以在需要的时候停止迭代。当您提供的回调函数返回true时,它停止。 此外,一些国际单项体育联合会可以简化。你在表演元素.名称检查是否有子元素,似乎可以单独放置。

    checkFilterValue(group, currentFilterName) {
      return group.some((element, index) => { 
        if (element.name === currentFilterName) {
            this.returnedValue = element.value
            return true;
            }
        else if (element.children) {
            return this.checkFilterValue(element.children || this.filtersConfig[index + 1], currentFilterName);
          }
        else
            return false;
        }
      )
    }
    
        4
  •  0
  •   arc    6 年前

    AnonymousSBs的答案非常简洁,但是你们两个都有严格意义上不需要的代码,他封装了递归部分,而我选择了noto。无论如何,递归方法可能是最好的方法。

    function checkFilterValue(group, currentFilterName) {
        for (let i = 0, element; element = group[i]; i++) {
    
            // use "return" to cancel loop early and return value
            // no need for else clause or break
            if (element.name === currentFilterName) {
                return this.returnedValue = element.value
            }
    
            // now we need to check if there are childern
            // not sure what filterConfig is, though, you may want to test this
            // index propably is the depth, and not the index of the loop
            let children = element.children || this.filtersConfig[i + 1]
            if (children) {
                return this.checkFilterValue(children, currentFilterName)
            }
    
        }
    }