【问题标题】:How to set an Object's values inside an array with ES6?如何使用 ES6 在数组中设置对象的值?
【发布时间】:2019-02-27 16:51:05
【问题描述】:

我正在寻找在数组中设置对象值的最快和最资源友好的方法。也可以使用 ES6 语法。

假设我有这个对象数组:

let group = [
    {
        id: 1,
        name: 'Test 1',
        geo: 'Japan',
        car: 'Toyota'
    },
    {
        id: 2,
        name: 'Test 2',
        geo: 'USA',
        car: 'Tesla'
    },
    {
        id: 3,
        name: 'Test 3',
        geo: 'Germany',
        car: 'Audi'
    }
];

我想根据用户输入获取这些对象之一。假设我们想通过对象的 ID 获取第 3 项的索引:

let index = group.findIndex(g => g.id === payload.id);

一旦我有了索引,我想像这样为这个对象分配新值:

group[index].id = payload.id;
group[index].name = payload.name;
group[index].geo = payload.geo;
group[index].car = payload.car;

但是它又长又丑,想象一下如果你在这个对象中有 50 多个值。

问题:有没有更短、更有效的方法来达到同样的效果?也包括 ES6-ES7 语法。

【问题讨论】:

  • ID 是唯一的吗?我的意思是,如果是这样,您可能根本不需要获取索引,并且解决方案会变得更简洁。
  • @vahdet 是的,ID 是唯一的。

标签: javascript ecmascript-6 ecmascript-2016


【解决方案1】:

使用索引。对于一次性搜索和更新,Array.find 效果很好。但是,如果您需要更新多个条目,则必须构建一个数组索引。

(function(){
    let group = [{ id: 1, name: 'Test 1', geo: 'Japan', car: 'Toyota' }, { id: 2, name: 'Test 2', geo: 'USA', car: 'Tesla' }, { id: 3, name: 'Test 3', geo: 'Germany', car: 'Audi' }],
        payload = { id: 3, name: 'update', geo: 'Germany Bavaria Ingolstadt', car: 'Audi 1' };
        
    let groupIndex = {};
    group.forEach(x => groupIndex[x.id]=x);

    let start = new Date().valueOf();
    let id = 1;
    let updates = 1000000;
    for(let i=0;i<updates;i++)
        if (groupIndex[id])
            Object.assign(groupIndex[id], payload);

    console.log(updates+" taken "+(new Date().valueOf()-start)+" ms");
})()

【讨论】:

    【解决方案2】:

    上面给出的解决方案是正确的,你也可以在一行中使用 map 做同样的事情(更喜欢使用 lodash map 函数)。

    let group = [{ id: 1, name: 'Test 1', geo: 'Japan', car: 'Toyota' }, { id: 2, name: 'Test 2', geo: 'USA', car: 'Tesla' }, { id: 3, name: 'Test 3', geo: 'Germany', car: 'Audi' }],
    payload = { id: 3, name: 'update', geo: 'Germany Bavaria Ingolstadt', car: 'Audi 1' }; 
    
    group = group.map((item) => item.id === payload.id ? payload : item);
    

    【讨论】:

    • 需要注意的重要一点是,在此解决方案中,您将用新对象替换整个对象,而在 Nina 和我的解决方案 1)中,您仅替换两个对象中的键值(@ 987654322@ 和 group[i]) 2) 仅在其中一个键中的值将保留在新对象中。
    【解决方案3】:
    el = group.find(g => g.id === payload.id);
    if (el) { // add this 'if' if you are not sure if payload's id will be in group
      idx = group.indexOf(el);
      group[idx] = {...el, ...payload};
    }
    

    【讨论】:

    • 无需使用.find 定位对象,然后使用该对象...定位索引。那是两次解析数组。您可以更改已经更改数组的el,也可以更改findIndex 来获取索引。然后将索引设置为 new 对象意味着旧的对象将被垃圾收集。或者更糟 - 不是 GCed,因为某些东西已经引用了它,现在它没有得到更新。
    【解决方案4】:

    您可以使用Array#findObject.assign 来更改找到的对象的属性。

    var group = [{ id: 1, name: 'Test 1', geo: 'Japan', car: 'Toyota' }, { id: 2, name: 'Test 2', geo: 'USA', car: 'Tesla' }, { id: 3, name: 'Test 3', geo: 'Germany', car: 'Audi' }],
        payload = { id: 3, name: 'update', geo: 'Germany Bavaria Ingolstadt', car: 'Audi 1' },
        object = group.find(({ id }) => id === payload.id);
    
    if (object) {
        Object.assign(object, payload);
    }
    
    console.log(group);
    .as-console-wrapper { max-height: 100% !important; top: 0; }

    【讨论】:

    • 完美按预期工作。非常感谢你做的这些! :-)
    猜你喜欢
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    • 2021-09-13
    • 2021-07-19
    • 1970-01-01
    • 2017-10-16
    相关资源
    最近更新 更多