【问题标题】:Increment a parameter in a javascript recursive function在javascript递归函数中增加参数
【发布时间】:2019-12-26 14:09:11
【问题描述】:

我将以下数据存储在一个变量中:

let categories = [
    {
    name: "a",
    selected: false,
    nodes: [
        {
        name: "aa",
        selected: false
      },
      {
        name: "ab",
        selected: true
      },
      {
        name: "ac",
        selected: true
      },
      {
        name: "ad",
        selected: false
      }
    ]
  },
  {
    name: "b",
    selected: false,
    nodes: [
        {
        name: "ba",
        selected: false
      },
      {
        name: "bb",
        selected: true
      },
      {
        name: "bc",
        selected: true
      },
      {
        name: "bd",
        selected: false
      }
    ]
  }
];

我想数一下selected = true有多少物品。
所以我创建了以下函数:

function getSelected(categories, counter = 0) {
    for (let index = 0; index < categories.length; index++) {
        const category = categories[index];
    if (category.selected) {
        counter++;
    }
    if (category.nodes && category.nodes.length) {
        category.nodes.forEach(cat => getSelected([cat], counter));
    }
    }
  return counter;
}

但它总是返回 0

A working jsFiddle

【问题讨论】:

    标签: javascript arrays object recursion


    【解决方案1】:

    您可以对节点进行递归减少并计数selected

    const
        countSelected = (s, o) => (o.nodes || []).reduce(countSelected, s + o.selected);
    
    let categories = [{ name: "a", selected: false, nodes: [{ name: "aa", selected: false }, { name: "ab", selected: true }, { name: "ac", selected: true }, { name: "ad", selected: false }] }, { name: "b", selected: false, nodes: [{ name: "ba", selected: false }, { name: "bb", selected: true }, { name: "bc", selected: true }, { name: "bd", selected: false }] }],
        count = categories.reduce(countSelected, 0);
    
    console.log(count);

    【讨论】:

    • PS:节点的深度是未知的,所以如果我们有更深的节点,reduce 将无法工作。
    • 它适用于所有嵌套的nodes 属性,因为它使用递归。请看一下countSelected的减少。
    【解决方案2】:

    这是因为 Number (and other primitives) 函数的参数重复,它创建了一个用参数值初始化的全新变量。

    您可以做的是使用函数的返回值并将其相加,或者您可以使用对象作为参数,因为它们是通过引用发送的,因此您保持相同的对象:

    let categories = [{name: "a",selected: false,nodes: [{name: "aa",selected: false},{name: "ab",selected: true},{name: "ac",selected: true},{name: "ad",selected: false}]},{name: "b",selected: false,nodes: [{name: "ba",selected: false},{name: "bb",selected: true},{name: "bc",selected: true},{name: "bd",selected: false}]}]
    
    function getSelectedWithObject(categories, counter = {val: 0}) {
        for (let index = 0; index < categories.length; index++) {
            const category = categories[index]
            if (category.selected) {
                counter.val++
            }
            if (category.nodes && category.nodes.length) {
                category.nodes.forEach(cat => getSelectedWithObject([cat], counter))
            }
        }
        return counter.val
    }
    
    function getSelectedWithReturnValue(categories) {
        let counter = 0
        for (let index = 0; index < categories.length; index++) {
            const category = categories[index]
            if (category.selected) {
                counter++
            }
            if (category.nodes && category.nodes.length) {
                category.nodes.forEach(cat => counter += getSelectedWithReturnValue([cat]))
            }
        }
        return counter
    }
    
    console.log(getSelectedWithObject(categories))
    console.log(getSelectedWithReturnValue(categories))

    【讨论】:

      【解决方案3】:

      counter 是一个整数,所以这里是按值传递的。 使counter 成为您想要从函数中返回的结果,然后就可以了:

      function getSelected(categories) {
          var counter = 0;
          for (let index = 0; index < categories.length; index++) {
              const category = categories[index];
              if (category.selected) {
                 counter++;
              }
              if (category.nodes && category.nodes.length) {
                 category.nodes.forEach(cat => counter += getSelected([cat]));
              }
          }
          return counter;
      }
      
      console.log(getSelected(categories));
      

      【讨论】:

        猜你喜欢
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-04
        • 2016-07-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多