Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update if exists or add new element to array of objects - elegant way in javascript + lodash

So I have an array of objects like that:

var arr = [   {uid: 1, name: "bla", description: "cucu"},   {uid: 2, name: "smth else", description: "cucarecu"}, ] 

uid is unique id of the object in this array. I'm searching for the elegant way to modify the object if we have the object with the given uid, or add a new element, if the presented uid doesn't exist in the array. I imagine the function to be behave like that in js console:

> addOrReplace(arr, {uid: 1, name: 'changed name', description: "changed description"}) > arr [   {uid: 1, name: "bla", description: "cucu"},   {uid: 2, name: "smth else", description: "cucarecu"}, ] > addOrReplace(arr, {uid: 3, name: 'new element name name', description: "cocoroco"}) > arr [   {uid: 1, name: "bla", description: "cucu"},   {uid: 2, name: "smth else", description: "cucarecu"},   {uid: 3, name: 'new element name name', description: "cocoroco"} ] 

My current way doesn't seem to be very elegant and functional:

function addOrReplace (arr, object) {   var index = _.findIndex(arr, {'uid' : object.uid});   if (-1 === index) {     arr.push(object);   } else {     arr[index] = object;   } }  

I'm using lodash, so I was thinking of something like modified _.union with custom equality check.

like image 227
ganqqwerty Avatar asked Sep 10 '14 11:09

ganqqwerty


People also ask

How do you update an array with new values?

To update all the elements of an array, call the forEach() method on the array, passing it a function. The function gets called for each element in the array and allows us to update the array's values. Copied! const arr = ['zero', 'one', 'two']; arr.

How do you update an array in JavaScript?

This built-in array method, provided by JavaScript, iterates over the original array and creates the new array, completing the elements based on the specified conditions. Instead of an arrow function, you can also pass the callback function.

What is pickBy Lodash?

Lodash is a JavaScript library that works on the top of underscore. js. Lodash helps in working with arrays, strings, objects, numbers, etc. The _. pickBy() method is used to return a copy of the object that composed of the object properties predicate returns truthy for.

How do you use sortBy Lodash?

Lodash helps in working with arrays, collection, strings, objects, numbers etc. The _. sortBy() method creates an array of elements which is sorted in ascending order by the results of running each element in a collection through each iteratee.


2 Answers

In your first approach, no need for Lodash thanks to findIndex():

function upsert(array, element) { // (1)   const i = array.findIndex(_element => _element.id === element.id);   if (i > -1) array[i] = element; // (2)   else array.push(element); } 

Example:

const array = [   {id: 0, name: 'Apple', description: 'fruit'},   {id: 1, name: 'Banana', description: 'fruit'},   {id: 2, name: 'Tomato', description: 'vegetable'} ];  upsert(array, {id: 2, name: 'Tomato', description: 'fruit'}) console.log(array); /* => [   {id: 0, name: 'Apple', description: 'fruit'},   {id: 1, name: 'Banana', description: 'fruit'},   {id: 2, name: 'Tomato', description: 'fruit'} ] */  upsert(array, {id: 3, name: 'Cucumber', description: 'vegetable'}) console.log(array); /* => [   {id: 0, name: 'Apple', description: 'fruit'},   {id: 1, name: 'Banana', description: 'fruit'},   {id: 2, name: 'Tomato', description: 'fruit'},   {id: 3, name: 'Cucumber', description: 'vegetable'} ] */ 

(1) other possible names: addOrReplace(), addOrUpdate(), appendOrUpdate(), insertOrUpdate()...

(2) can also be done with array.splice(i, 1, element)

Note that this approach is "mutable" (vs "immutable"): it means instead of returning a new array (without touching the original array), it modifies directly the original array.

like image 77
tanguy_k Avatar answered Oct 09 '22 02:10

tanguy_k


You can use an object instead of an array:

var hash = {   '1': {uid: 1, name: "bla", description: "cucu"},   '2': {uid: 2, name: "smth else", description: "cucarecu"} }; 

The keys are the uids. Now your function addOrReplace is simple like this:

function addOrReplace(hash, object) {     hash[object.uid] = object; } 

UPDATE

It's also possible to use an object as an index in addition to the array.
This way you've got fast lookups and also a working array:

var arr = [],     arrIndex = {};  addOrReplace({uid: 1, name: "bla", description: "cucu"}); addOrReplace({uid: 2, name: "smth else", description: "cucarecu"}); addOrReplace({uid: 1, name: "bli", description: "cici"});  function addOrReplace(object) {     var index = arrIndex[object.uid];     if(index === undefined) {         index = arr.length;         arrIndex[object.uid] = index;     }     arr[index] = object; } 

Take a look at the jsfiddle-demo (an object-oriented solution you'll find here)

like image 38
friedi Avatar answered Oct 09 '22 01:10

friedi