如何在对象内部执行递归reduce函数
How to do a recursive reduce function inside an object?
我在使用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": []
},
...
]
},
...
]
进入这个:
[
{
"id": 10,
"text": "Designer"
},
{
"id": 11,
"text": "UI / Visual Designer",
},
{
"id": 1,
"text": "Software Engineer",
},
{
"id": 2,
"text": "Back-End Developer",
}
...
]
我在练习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;
}, []);
},
...
}
所以,正如您所看到的,我不得不调用jobNewPage.buildArrayForSelect(children)
来递归地执行它。我尝试调用this.buildArrayForSelect(children)
,但上下文不同。我觉得这不是最好的选择,因为我不想依赖于调用对象中函数内部的全局变量。我该如何改进?
当函数使用函数表达式定义并分配给更高范围对象上的属性时,您的问题似乎可以归结为如何从函数内部递归调用该函数。
简单的答案是将其转换为命名函数表达式。这样的函数能够递归地调用自己:
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);
这种方法应用于您的对象和函数,看起来如下:
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;
}, []);
}
}
示例如何以递归方式将Array.prototype.reduce
与Array.prototype.concat
组合使用。
var data = [{ "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": [] }] }];
function getAll(array) {
return array.reduce(function (r, a) {
r.push({ id: a.id, text: a.name });
if (a.children && Array.isArray(a.children)) {
r = r.concat(getAll(a.children));
}
return r;
}, []);
}
document.write('<pre>' + JSON.stringify(getAll(data), 0, 4) + '</pre>');
试试这个:
Array.prototype.flatten = function () {
return this.reduce(function (acc, value) {
acc.push(value);
acc = acc.concat(value.children.flatten());
return acc;
}, []);
};
Array.prototype.extractData = function () {
return this.map(function(a) {
return (a.slug!='remote')?{'id':a.id,'text':a.name}:false
}).filter(function(a) {
return (a!=false)?a:false;
});
};
提取数据:
options=array.flatten().extractData();
Js报价
我刚刚意识到,我的答案采用了与詹姆斯·索普的答案类似的方法(尤其是dfsq在评论中提出的解决方案)。然而,他的执行似乎比我的效率高得多。
您可以将其作为立即调用函数表达式来执行。假设你的树结构在变量"树"中;
var tree = []; //your original tree stucture
var result = (function(input) {
var flattened = [];
var flattener = function(collection) {
collection.forEach(function(item) {
flattened.push({id: item.id, text: item.name});
if (item.children.length > 0) {
flattener(item.children);
}
});
}
flattener(input);
return flattened;
})(tree);
console.log(result);
相关文章:
- 数组在递归方法中设置为null
- Kendo:我该如何在树视图中创建一个递归的hieiarchy
- 递归使用 eval() 是检查程序执行的好方法吗?
- 使用递归、Ramda.js和无点样式重构字符串的getPermutations()
- 递归深度比较
- Eloquent JavaScript递归示例如何终止为返回1,但仍然输出指数值
- 递归函数中断
- 如何递归地获取嵌套对象中所有子对象的列表
- JavaScript 素数搜索无限递归
- 在递归生成器函数中,yield后面的*(星号/星号)语法意味着什么
- 递归|两个函数名
- 有没有一种方法可以在Javascript中进行可变递归currying
- 如何对不同的表递归使用以下代码
- 将jQuery对象传递到setTimeout递归函数中
- 有更好的方法吗?(递归解析HTML unicode实体)
- 为什么递归生成器函数没有't在ES2015工作
- 使用递归实现加性持久性
- 递归显示n元树
- 如何在对象内部执行递归reduce函数
- 递归函数中的Array.prototype.reduce产生了意想不到的结果