代码之家  ›  专栏  ›  技术社区  ›  Ayoub k

在javascript递归函数中增加一个参数

  •  1
  • Ayoub k  · 技术社区  · 5 年前

    我在变量中存储了以下数据:

    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

    4 回复  |  直到 5 年前
        1
  •  3
  •   Nina Scholz    5 年前

    可以递归地减少节点和计数 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);
        2
  •  2
  •   jonatjano    5 年前

    是因为 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
  •  1
  •   Omar Mneimneh    5 年前

    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));