使用传播将数组映射到对象

Posted

技术标签:

【中文标题】使用传播将数组映射到对象【英文标题】:Mapping array to object using spread 【发布时间】:2018-02-27 15:24:41 【问题描述】:

我想将跟随数组转换为稍微修改的对象(见下文)。我也在尝试练习使用扩展运算符,但一直无法弄清楚如何做到这一点。我试图避免使用 lodash(用于教育目的)。

起始数组:

var arr = [
     mainkey: 'John', val1: 'ABC', val2: '..', val3: '..' ,
     mainkey: 'Mary', val1: 'DEF', val2: '..', val3: '..' ,
     mainkey: 'Ann', val1: 'XYZ', val2: '..', val3: '..' 
  ];

到最终对象:

newObj = 
  John: val1: 'ABC', val2: '..', val3: '..' ,
  Mary: val1: 'DEF', val2: '..', val3: '..' ,
  Ann:  val1: 'XYZ', val2: '..', val3: '..' 

不使用扩展运算符,这很接近,但不是我需要的:

var result = arr.reduce(function(map, obj) 
    map[obj.mainkey] = obj.val1;
    // map[obj.mainkey] =  obj.val1, obj.val2 ; <-- DOESNT WORK
    return map;
, );

使用扩展运算符,我所做的任何事情都会失败。

其他内容有用的帖子:

React object spread (ES6) returned from map Convert object array to hash map, indexed by an attribute value of the Object

【问题讨论】:

【参考方案1】:

简答

const newObj = arr.reduce(
    (acc,  mainkey, ...rest ) => ( ...acc, [mainkey]: rest ),
    
  )

解释

我们调用Array.prototype.reduce(),对于数组中的每个对象,从其余属性中解构mainkey(因此mainkey 可能是Johnrest 可能是像这样的东西:val1: 'ABC', val2: '..', val3: '..'

然后,我们想要返回一个深度变化的累加器,所以我们使用扩展运算符,然后将插入的mainkey 属性([mainkey])设置为rest

【讨论】:

感谢@guy 的解释,这很有帮助(特别是因为我出于教育目的而尝试这样做,即使我的应用程序也需要它)【参考方案2】:

只需更改为..

    var result = arr.reduce(function(map, obj) 
        map[obj.mainkey] = 
            val1: obj.val1,
            val2: obj.val2,
        ;
        return map;
    , );        

更新: 添加其他动态版本。

var result = arr.reduce(function(map, obj) 
    let targetProps = Object.getOwnPropertyNames(obj).filter(
        (prop) => prop !== "mainkey"
    );
    map[obj.mainkey] = ;
    targetProps.forEach( (prop) => 
        map[obj.mainkey][prop] = obj[prop];
    );
    return map;
, );   

【讨论】:

感谢@panghea 展示了如何改编我的原作! 如果您有兴趣帮助我完成此版本:您将如何处理拥有 10 多个值而不必将它们全部拼出(或动态数量?) 添加动态版本:) 你太棒了!

以上是关于使用传播将数组映射到对象的主要内容,如果未能解决你的问题,请参考以下文章

在对象数组中传播语法

如何将对象作为方法输入参数而不是作为参数数组传播?

Vue 将对象作为计算属性传播

在某个索引之后传播值

如何将 3d 数组传播到由 3 个单独的表数据标签组成的表中?

在PHP中传播变量