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.
You can use an object instead of an array:
The keys are the uids. Now your function
addOrReplace
is simple like this: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:
Take a look at the jsfiddle-demo (an object-oriented solution you'll find here)
What about having the indexes of the array same as the
uid
?, like:that way you could just simply use
In your first approach, no need for Lodash thanks to
findIndex()
:Example:
(1) other possible names:
addOrUpdate()
,upsert()
,appendOrUpdate()
,insertOrUpdate()
...(2) Can also be done with
array.splice(i, 1, item)
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. Most of the time, this is what you want.
I personally do not like solutions that modify the original array/object, so this is what I did:
And you would use it like:
What I decided to do was to make it more flexible:
lodash -> _.findIndex()
, the predicate can be multiple thingsgetItem()
, you can decide whether to fully replace the item or do some modifications, as I did in my example.Note: this solution contains some ES6 features such as destructuring, arrow functions, among others.
Old post, but why not use the filter function?
Here is a jsfiddle showing how it works.
Maybe
and