简体   繁体   English

为什么以下map函数产生未定义的对象?

[英]Why does the following map function produce undefined objects?

I have an array context.buildingFields.finished that looks like this: 我有一个数组context.buildingFields.finished看起来像这样:

[{ name: 'a' type: 'text', value: '1' }, { name: 'b' type: 'file', value: '2' }] 

And I have a function that loops through that array to create a new one context.createPanoramasPayload with only the fields of type file : 我有一个函数遍历该数组以创建一个新的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)
  }
}

I thought I would produce something like this (say with only one field of type file ): 我以为我会产生这样的内容(例如,只包含一个类型为file字段):

[{ name: 'b' type: 'file', value: '2' }] 

However, what I'm getting is something like this: 但是,我得到的是这样的:

[undefined, { name: 'b' type: 'file', value: '2' }] 

Why is this? 为什么是这样? And how to modify the code to achieve what I want? 以及如何修改代码以实现我想要的?

map returns an array that has the same length as the given array. map返回一个与给定数组具有相同长度的数组。 It does not help to return just like that, as that will generate an undefined value in your mapped array. 那样return是没有帮助的,因为那样会在映射数组中生成一个undefined值。 Instead you need to apply filter first: 相反,您需要首先应用filter

context.createPanoramasPayload = panoramasFields.filter(field => {
    return field.type === 'file';
}).map(field => {
    return {
        name: 'index',
        value: uploadedPhoto
    }
})

This keeps with a functional way of programming. 这与功能性的编程方式保持一致。

As a side note, since the callback functions now don't do anything else than return something, you can use the expression syntax for the arrow functions: 附带说明一下,由于回调函数现在除了返回内容外不执行其他任何操作,因此可以对箭头函数使用表达式语法:

context.createPanoramasPayload = panoramasFields
    .filter(field => field.type === 'file')
    .map(field => ({
        name: 'index',
        value: uploadedPhoto
    }));

You are using map function here, that means it will not reduce the length of the array. 您在这里使用map函数,这意味着它不会减少数组的长度。 It return same length array. 它返回相同长度的数组。 So use filter to get result. 因此,使用过滤器可获得结果。

This answer is an extension to @ trincot 's answer. 此答案是@ Trincot答案的扩展。

Using .filter + .map is not wrong, but it adds to extra iterations. 使用.filter + .map没错,但是它增加了额外的迭代。 Both these functions have their own specific use-case but when you need to do both, .reduce is more suited as you can manually parse object and return custom array/object . 这两个函数都有其特定的用例,但是当您需要同时使用这两个函数时, .reduce更适合,因为您可以手动解析对象并返回自定义数组/对象

Sample 样品

context.createPanoramasPayload = panoramasFields.reduce(function(p, c) {
  if (c.type === 'file')
    p.push({
      name: 'index',
      value: uploadedPhoto
    });
  return p;
}, [])

Also note the use of anonymous function instead of arrow function ( => ). 还要注意使用匿名函数代替箭头函数=> )。

What arrow function does is it binds current context to the passed callback function, so that we can use this inside the callback. 箭头函数的作用是将当前上下文绑定到传递的回调函数,以便我们可以在回调内部使用this If you are using arrow function but not using this inside callback, you are wasting the efforts engine puts in binding context to the callback. 如果您使用的是箭头功能,但未在回调内部使用this函数,那么您浪费的是引擎将上下文绑定到回调中。 For this reason, if you do not use this , in my understanding, its better to use anonymous function instead of arrow function. 因此,如果您不使用this ,以我的理解,最好使用匿名函数而不是箭头函数。

Though its not wrong, but in my POV, it is a bad practice. 虽然它没有错,但是在我的POV中,这是一种不良做法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM