什么';下面JavaScript reduce函数的模式是什么?
我无法理解以下reduce函数:什么';下面JavaScript reduce函数的模式是什么?,javascript,mapreduce,Javascript,Mapreduce,我无法理解以下reduce函数: function findDeep(arr, obj) { return arr.map(item => { if (item.name === obj.name) { return arr } else if (item.children) { return findDeep(item.children, obj) } else { return undefined } }).r
function findDeep(arr, obj) {
return arr.map(item => {
if (item.name === obj.name) {
return arr
} else if (item.children) {
return findDeep(item.children, obj)
} else {
return undefined
}
}).reduce((prev, curr) => {
console.log('prev: ', prev)
console.log('curr: ', curr)
return prev || curr
})
}
应用于此对象:
const mockApps = {
name: 'orange',
children: [{
name: 'white'
}, {
name: 'green',
children: [{
name: 'yellow',
children: [{
name: 'red'
}, {
name: 'white'
}]
}, {
name: 'green',
children: [{
name: 'purple'
}]
}]
}, {
name: 'gray'
}]
}
const activeApp = {
name: 'purple',
color: 'purple',
path: 'writer'
}
findDeep(mockApps.children, activeApp)
我认为模式将类似于以下示例:
但令我惊讶的是,我的理论与输出不同:
我原以为previousValue
将是上一次迭代的returnValue
,但正如您在控制台中看到的,第三次prev
未定义,即使上一次迭代的currentValue
未定义
此reduce
功能的正确模式是什么
以下是。您似乎假设控制台输出属于一次运行的
reduce
,但事实并非如此
函数findDeep
递归调用自身,因此您将从对reduce
的不同调用中获得输出
我建议您修改以下代码,以便在调用并退出findDeep
时也能在控制台中看到:
function findDeep(arr, obj) {
console.log('Entering findDeep');
var res = arr.map(item => {
if (item.name === obj.name) {
return arr
} else if (item.children) {
return findDeep(item.children, obj)
} else {
return undefined
}
}).reduce((prev, curr) => {
console.log('prev: ' + JSON.stringify(prev));
console.log('curr: ' + JSON.stringify(curr));
console.log('return: ' + JSON.stringify(prev || curr));
return prev || curr;
});
console.log('Exiting from findDeep');
return res;
}
这应该会让问题变得明朗起来。以下是将日志写入浏览器的代码段:
console={log:function(msg){
编写(msg+“
”);
}}
功能findDeep(arr、obj){
console.log('进入findDeep');
var res=arr.map(项目=>{
if(item.name==对象名){
返回arr
}else if(项。子项){
返回findDeep(item.children,obj)
}否则{
返回未定义
}
}).减少((上一个,当前)=>{
log('prev:'+JSON.stringify(prev));
log('curr:'+JSON.stringify(curr));
log('return:'+JSON.stringify(prev | | curr));
返回上一个| | curr;
});
log('从findDeep退出');
返回res;
}
常量mockApps={
名称:“橙色”,
儿童:[{
姓名:“白色”
}, {
名称:'绿色',
儿童:[{
名称:“黄色”,
儿童:[{
姓名:“红色”
}, {
姓名:“白色”
}]
}, {
名称:'绿色',
儿童:[{
名字:“紫色”
}]
}]
}, {
姓名:“格雷”
}]
}
常量activeApp={
名称:“紫色”,
颜色:'紫色',
路径:“作者”
}
findDeep(mockApps.children,activeApp)
您似乎假设控制台输出属于一次运行的reduce
,但事实并非如此
函数findDeep
递归调用自身,因此您将从对reduce
的不同调用中获得输出
我建议您修改以下代码,以便在调用并退出findDeep
时也能在控制台中看到:
function findDeep(arr, obj) {
console.log('Entering findDeep');
var res = arr.map(item => {
if (item.name === obj.name) {
return arr
} else if (item.children) {
return findDeep(item.children, obj)
} else {
return undefined
}
}).reduce((prev, curr) => {
console.log('prev: ' + JSON.stringify(prev));
console.log('curr: ' + JSON.stringify(curr));
console.log('return: ' + JSON.stringify(prev || curr));
return prev || curr;
});
console.log('Exiting from findDeep');
return res;
}
这应该会让问题变得明朗起来。以下是将日志写入浏览器的代码段:
console={log:function(msg){
编写(msg+“
”);
}}
功能findDeep(arr、obj){
console.log('进入findDeep');
var res=arr.map(项目=>{
if(item.name==对象名){
返回arr
}else if(项。子项){
返回findDeep(item.children,obj)
}否则{
返回未定义
}
}).减少((上一个,当前)=>{
log('prev:'+JSON.stringify(prev));
log('curr:'+JSON.stringify(curr));
log('return:'+JSON.stringify(prev | | curr));
返回上一个| | curr;
});
log('从findDeep退出');
返回res;
}
常量mockApps={
名称:“橙色”,
儿童:[{
姓名:“白色”
}, {
名称:'绿色',
儿童:[{
名称:“黄色”,
儿童:[{
姓名:“红色”
}, {
姓名:“白色”
}]
}, {
名称:'绿色',
儿童:[{
名字:“紫色”
}]
}]
}, {
姓名:“格雷”
}]
}
常量activeApp={
名称:“紫色”,
颜色:'紫色',
路径:“作者”
}
findDeep(mockApps.children,activeApp)
如果按照代码进行操作,则传递到map(级别0)的第一个值是:
它没有紫色或任何子级名称,因此结果数组现在为:
[undefined]
[undefined]
[{name:'purple'}]
下一项是:
{name: 'green',
children: [{
name: 'yellow',
children: [{
name: 'red'
}, {
name: 'white'
}]
}, {
name: 'green',
children: [{
name: 'purple'
}]
}]
}
它有一个children属性,因此它的值被传递给对findDeep的递归调用(级别1),即:
[{
name: 'yellow',
children: [{
name: 'red'
}, {
name: 'white'
}]
}, {
name: 'green',
children: [{
name: 'purple'
}]
}]
传递给map的第一个项,再次递归调用findDeep(第2级),使用:
第一项没有紫色或子项的名称,因此此级别映射数组现在为:
[undefined]
[undefined]
[{name:'purple'}]
下一项也一样,所以现在是:
[undefined, undefined]
下一个名称为“紫色”,因此将其添加到数组中:
[undefined, undefined,{name:'purple'}]
这是通过reduce运行的,reduce调用时没有累加器,因此前两个值作为prev和cur传递。由于prev为false,curr的值作为累加器返回,因此在下一次调用中,值未定义且{name:'purple'}
,因此返回到级别1映射,其数组现在为:
[undefined]
[undefined]
[{name:'purple'}]
此级别中没有更多成员,因此将传递给reduced。由于它是数组中唯一的成员,并且没有传入累加器,因此只返回它,因此级别1的结果是:
[{name:'purple'}]
[{name:'purple'}]
级别0的最后一个成员也返回undefined,因此最终的级别0数组是:
[{name:'purple'}, undefined]
它被传递到reduce,两个值分别为prev和curr。由于prev对象不是false,因此返回该对象,最终结果为:
[{name:'purple'}]
[{name:'purple'}]
请注意,如果使用JSON.stringify查看对象和数组,undefined将更改为“null”。如果按照代码进行操作,则传递给map(级别0)的第一个值是: 它没有紫色或任何子级名称,因此结果数组现在为:
[undefined]
[undefined]
[{name:'purple'}]
下一项是:
{name: 'green',
children: [{
name: 'yellow',
children: [{
name: 'red'
}, {
name: 'white'
}]
}, {
name: 'green',
children: [{
name: 'purple'
}]
}]
}
它有一个children属性,因此它的值被传递给对findDeep的递归调用(级别1),即:
[{
name: 'yellow',
children: [{
name: 'red'
}, {
name: 'white'
}]
}, {
name: 'green',
children: [{
name: 'purple'
}]
}]
传递给map的第一个项,再次递归调用findDeep(第2级),使用:
第一项没有紫色或子项的名称,因此此级别映射数组现在为:
[undefined]
[undefined]
[{name:'purple'}]
下一项也一样,所以现在是:
[undefined, undefined]
下一个名称为“紫色”,因此将其添加到数组中:
[undefined, undefined,{name:'purple'}]
这是通过reduce运行的,reduce调用时没有累加器,因此前两个值作为prev和cur传递。因为prev是fal