【问题标题】:Return multiple values from ES6 map() function从 ES6 map() 函数返回多个值
【发布时间】:2018-04-09 17:57:09
【问题描述】:

假设我有这样的事情:

let values = [1,2,3,4]; 

let newValues = values.map((v) => {
  return v *v ; 
}); 

console.log(newValues); //[1,4,9,16]

非常直接。

现在,如果我想为每个对象返回多个值怎么办?

例如。

let values = [1,2,3,4]; 

let newValues = values.map((v) => {
  return [v *v, v*v*v, v+1] ; 
}); 

console.log(newValues); //This is what I want to get 
                        //[1, 1, 2, 4, 8, 3, 9, 27, 4, 16, 64, 5]

我可以使用reduce函数

let values = [1,2,3,4]; 

let newValues = values.map((v) => {
  return [v *v, v*v*v,v+1] ;
}).reduce((a, c) => {

  return a.concat(c); 
}); 

console.log(newValues); 

但这是最好的方法吗?

【问题讨论】:

标签: collections ecmascript-6 flatmap


【解决方案1】:

只需使用一个reduce(),您就可以做到这一点。你不需要map()。 更好的方法是:

const values = [1,2,3,4];
const newValues= values.reduce((acc, cur) => {
  return acc.concat([cur*cur , cur*cur*cur, cur+1]);
    // or acc.push([cur*cur , cur*cur*cur, cur+1]); return acc;
}, []);

console.log('newValues =', newValues)

编辑: 更好的方法是使用 flatMap(如@ori-drori 所述):

const values = [1,2,3,4]; 

const newValues = values.flatMap((v) => [v *v, v*v*v, v+1]); 

console.log(JSON.stringify(newValues)); //[1, 1, 2, 4, 8, 3, 9, 27, 4, 16, 64, 5]

【讨论】:

  • 为什么不直接使用.push() 而不是每次循环都创建一个新数组呢?您可以将多个值传递给.push()。事实上,你也不需要使用.reduce()for/of.forEach() 可以很好地工作,您只需将 .push() 值放入先前声明的数组中。
  • @jfriend00 因为reduce() 是一种函数式编程方法(我的优先级)。当然,您的解决方案也可以正常工作。
  • 不喜欢,因为 (1) 这非常慢 - On^2 - 并且 (2) 有一个内置的 fn flatMap 不需要不良做法(除了实现另一个功能官方的)
【解决方案2】:

如果您需要映射一个数组,并将结果展平,您可以使用Array.flatMap()

const values = [1,2,3,4]; 

const newValues = values.flatMap((v) => [v *v, v*v*v, v+1]); 

console.log(JSON.stringify(newValues)); //[1, 1, 2, 4, 8, 3, 9, 27, 4, 16, 64, 5]

如果Array.flatMap() 不可用,则使用Array#concatspread syntax 拼合地图结果:

const values = [1,2,3,4]; 

const newValues = [].concat(...values.map((v) => [v *v, v*v*v, v+1])); 

console.log(JSON.stringify(newValues)); //[1, 1, 2, 4, 8, 3, 9, 27, 4, 16, 64, 5]

【讨论】:

  • 这很漂亮。非常巧妙地使用了concat 如何处理多个数组参数。
  • TypeError: flatMap is not a function 我在节点 v10.18.1 中收到此错误
  • node v10中不支持,但是有polyfills,也可以使用答案中的[].concat()解决方案。
  • 其他选择是使用.map().flat()
【解决方案3】:

根据定义,.map() 返回一个与输入数组长度相同的数组,因此当您想要创建不同长度的结果时,它不是一个好的选择。

从效率的角度来看,最好使用for/of 并避免创建大量中间数组:

let values = [1,2,3,4];

let result = [];
for (let val of values) {
    result.push(val*val , val*val*val, val+1);
}

如果您想有效地使用数组方法,可以使用 .reduce().push() 以避免在每次迭代时创建新数组:

let values = [1,2,3,4]; 

let result = values.reduce((array, val) => {
    array.push(val*val , val*val*val, val+1);
    return array;
}, []);

【讨论】:

    【解决方案4】:

    lodash更好地使用flatMap

     const output = _.flatMap([1,2,3,4], (v, index, arr) => [v *v, v*v*v, v+1])
    

    输出:[ 1、 1、 2、 4、 8、 3、 9、 27, 4、 16, 64, 5 ]

    【讨论】:

      猜你喜欢
      • 2013-09-18
      • 1970-01-01
      • 2018-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-04-29
      • 2019-06-09
      • 1970-01-01
      相关资源
      最近更新 更多