如何在对象内部执行递归reduce函数?

fes*_*sja 8 javascript recursion reduce

我在客户端用Javascript做这个.我想改造:

[
  {
    "id": 10,
    "name": "Designer",
    "slug": "designer",
    "children": [
      {
        "id": 11,
        "name": "UI / Visual Designer",
        "slug": "ui-visual-designer",
        "children": []
      },
      ...
    ]
  },
  {
    "id": 1,
    "name": "Software Engineer",
    "slug": "software-engineer",
    "children": [
      {
        "id": 2,
        "name": "Back-End Developer",
        "slug": "back-end-developer",
        "children": []
      },
      ...
    ]
  },
  ...
]
Run Code Online (Sandbox Code Playgroud)

进入这个:

[
  {
    "id": 10,
    "text": "Designer"
  },
  {
    "id": 11,
    "text": "UI / Visual Designer",
  },
  {
    "id": 1,
    "text": "Software Engineer",
  },
  {
    "id": 2,
    "text": "Back-End Developer",
  }
  ...
]
Run Code Online (Sandbox Code Playgroud)

我与练习map和reduce,所以我试图避免for环路(我做的第一件事).这是我目前的代码:

var jobNewPage = {
    ...
    buildArrayForSelect(array) {
        "use strict";
        return $.extend(true, [], array).reduce(function(total, item) {
            if ( item.slug == 'remote' ) return total;

            total.push({
                'id'   : item.id,
                'text' : item.name
            });

            let children = item.children;
            if (children && children.length) {
                // TODO: We had to call the global context jobNewPage
                total = total.concat(jobNewPage.buildArrayForSelect(children));
            }
            return total;
        }, []);
    },
    ...
}
Run Code Online (Sandbox Code Playgroud)

所以,正如你所看到的,我不得不打电话jobNewPage.buildArrayForSelect(children)来递归地做.我试着打电话,this.buildArrayForSelect(children)但背景不同.我觉得这不是最好的选择,因为我不想依赖于在对象中的函数内调用全局变量.我怎样才能改进它?

Jam*_*rpe 5

看来你的问题归结为如何从递归自身内部调用一个函数,当该功能正在使用函数表达式定义并分配到属性范围的更高的对象.

简单的答案是将其转换为命名函数表达式.这些函数能够递归调用自己:

var obj = {
   myMethod: function myName(n) { //function expression has name "myName"...
     console.log(n);
     if (n > 0)
       myName(n-1); //...which we can use inside the function...
   }
}

//...and outside we refer to the object's property name
obj.myMethod(5);
Run Code Online (Sandbox Code Playgroud)

这种方法适用于您的对象和函数,如下所示:

var jobNewPage = {
    //give the function expression a name:
    buildArrayForSelect: function buildArrayForSelect(array) {
        "use strict";
        return $.extend(true, [], array).reduce(function(total, item) {
            if ( item.slug == 'remote' ) return total;

            total.push({
                'id'   : item.id,
                'text' : item.name
            });

            let children = item.children;
            if (children && children.length) {
                //No need to reference object to call the function recursively:
                total = total.concat(buildArrayForSelect(children));
            }
            return total;
        }, []);
    }
}
Run Code Online (Sandbox Code Playgroud)