1

I'm looking for the quickest and most resource friendly way of setting an Object's values inside an array. Can use ES6 syntax as well.

So let's say I have this array of objects:

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'
    }
];

And I want to get one of these objects based on user input. Let's say we want to get the 3rd item's index by Obejct's ID:

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

Once I have the index I want to assign new values to this object like this:

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

However it is long, ugly, and imagine if you'd have 50+ values inside this object.

Question: Is there any shorter and more efficient way of achieving the same? Including ES6-ES7 syntaxes also.

2
  • Are the ids unique? I mean, if so, you may not require getting the index at all and the solution would become briefer. Commented Sep 24, 2018 at 7:59
  • @vahdet Yep, the IDs are unique. Commented Sep 24, 2018 at 8:01

4 Answers 4

3

You could use Array#find and Object.assign for changing the properties of the found object.

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; }

Sign up to request clarification or add additional context in comments.

1 Comment

Perfect works as expected. Thank you so much for this! :-)
2

Above given solution is correct, You can also do same using map in a single line (prefer to use lodash map 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' }; 

group = group.map((item) => item.id === payload.id ? payload : item);

1 Comment

What's important to note is that in this solution you will REPLACE the entire object with a new one, while in Nina's and mine solution 1) you are replacing only values of keys which are in both objects (payload and group[i]) 2) values which keys are only in one of those will stay in new object.
1
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};
}

1 Comment

There is no need to use .find to locate an object then use the object to...locate the index. That's parsing the array two times. You can either change el which already changes the array or findIndex to just grab the index. Then setting the index to a new object means the old one would be garbage collected. Or worse - not GCed because something already referenced it and it now doesn't get the update.
1

Use indexing. For one-time search&update the Array.find works well. But if you need to update more than one entry you have to build an array index.

(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");
})()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.