我有一个如下所示的数组context.buildingFields.finished
:
[{ name: 'a' type: 'text', value: '1' }, { name: 'b' type: 'file', value: '2' }]
我有一个循环遍历该数组的函数来创建一个新的context.createPanoramasPayload
,只有 类型为file
的字段:
function handleCreatePanoramas (uploadedPhoto, context, callback) {
const panoramasFields = context.buildingFields.finished
context.createPanoramasPayload = panoramasFields.map(field => {
if (field.type !== 'file') return
return {
name: 'index',
value: uploadedPhoto
}
})
callback(context.createPanoramasPayload)
}
}
我以为我会生成这样的东西(比如只有一个file
类型的字段):
[{ name: 'b' type: 'file', value: '2' }]
但是,我得到的是这样的:
[undefined, { name: 'b' type: 'file', value: '2' }]
这是为什么?以及如何修改代码以实现我想要的目标?
答案 0 :(得分:3)
map
返回一个与给定数组长度相同的数组。这对return
没有帮助,因为它会在映射数组中生成undefined
值。相反,您需要首先应用filter
:
context.createPanoramasPayload = panoramasFields.filter(field => {
return field.type === 'file';
}).map(field => {
return {
name: 'index',
value: uploadedPhoto
}
})
这与功能性编程方式保持一致。
作为旁注,由于回调函数现在除了返回一些东西之外什么都不做,你可以使用箭头函数的表达式语法:
context.createPanoramasPayload = panoramasFields
.filter(field => field.type === 'file')
.map(field => ({
name: 'index',
value: uploadedPhoto
}));
答案 1 :(得分:0)
您在这里使用 map 功能,这意味着它不会减少数组的长度。它返回相同长度的数组。因此,使用过滤器来获取结果。
答案 2 :(得分:0)
这个答案是@ trincot答案的延伸。
使用.filter
+ .map
没有错,但它会增加额外的迭代次数。这两个函数都有自己的特定用例,但是当你需要同时执行这两个函数时,.reduce
更适合,因为你可以手动解析对象并返回自定义数组/对象。
<强>示例强>
context.createPanoramasPayload = panoramasFields.reduce(function(p, c) {
if (c.type === 'file')
p.push({
name: 'index',
value: uploadedPhoto
});
return p;
}, [])
另请注意使用匿名函数而不是箭头函数(=>
)。
箭头函数的作用是将当前上下文绑定到传递的回调函数,以便我们可以在回调中使用this
。如果您正在使用箭头功能但不在回调中使用this
,那么您就是在浪费引擎将绑定上下文放入回调中的努力。因此,如果您不使用this
,根据我的理解,最好使用匿名函数而不是箭头函数。
虽然没有错,但在我的POV中,这是一个不好的做法。