return array of objects - javascript

I have the solution but Is there any other nicer way to do in javascript or is it possible to modify the arr1 itself and have arr1 as array of objects alone
I have array of objects and string
arr1 = [{
id: 'id1',
name: 'name1'
}, {
id: 'id2',
name: 'name2'
}, '/roll', '/roll1'];
i would like to have array of objects alone at the end
newarr1 = [{
id: "id1",
name: "name1"
}, {
id: "id2",
name: "name2"
}]
current solution
arr1.map((item) => {
if (typeof item === 'object') return newarr1.push(item)
})

newArr = arr1.filter(item => typeof item === 'object')

const isObject = item => Object.getPrototypeOf(item) === Object.prototype;
const newarr1 = arr1.filter(isObject);
Demo
const isObject = item => Object.getPrototypeOf(item) === Object.prototype;
const arr1 = [{id: 'id1', name: 'name1'}, {id: 'id2', name: 'name2'}, '/roll', '/roll1'];
const newarr1 = arr1.filter(isObject);
console.log(newarr1);

Related

How to conditionally insert object to an array with the spread operator based on a string value

I have a foo and a bar object that both have an id prop:
{ id: fooId, name: 'John' }
{ id: barId, name: 'Jane' }
I want to create an array arr of these objects but only insert the object to the arr if the id is not empty. I've tried this, but it leaves an empty object inside my array:
const fooId = '';
const barId = '2021';
const arr = [
...[(fooId ? {id: fooId, name: 'John'} : {})],
...[(barId ? {id: barId, name: 'Jane'} : {})],
];
console.log(arr.length);
And I want arr.length === 1 in this case.
Return an array with an object, or an empty array if the id is empty, and spread it.
const fooId = '';
const barId = '2021';
const arr = [
...fooId ? [{id: fooId, name: 'John'}] : [],
...barId ? [{id: barId, name: 'Jane'}] : [],
];
console.log(arr.length);
However, it's easier and cleaner to add the objects to the array, and then filter them out if the id is empty:
const fooId = '';
const barId = '2021';
const arr = [
{id: fooId, name: 'John'},
{id: barId, name: 'Jane'},
].filter(o => o.id);
console.log(arr.length);
Here you go:
const fooId = '';
const barId = '2021';
const arr = [
...fooId && [{ id: fooId, name: 'John' }],
...barId && [{ id: barId, name: 'Jane' }],
];
console.log(arr);
Or like this one:
const fooId = '';
const barId = '2021';
const arr = [
fooId && { id: fooId, name: 'John' },
barId && { id: barId, name: 'Jane' },
].filter(Boolean);
console.log(arr);

Return a subset of an array of objects that matches a property of an another array of objects

inputs:
const parentArray = [
{id:1, name:'foo'},
{id:2, name:'bar'},
{id:4, name:'foobar'},
{id:6, name:'barfoo'}
]
const childArray = [
{parent_id:1, prop:'prop1'},
{parent_id:2, prop:'prop2'},
{parent_id:3, prop:'prop3'},
{parent_id:4, prop:'prop4'},
{parent_id:5, prop:'prop5'}
];
output:
const resultingArray = [
{id:1, name:'foo'},
{id:2, name:'bar'},
{id:4, name:'foobar'}
]
I want to compare the properties id and parent_id from both arrays and return a subset of parentArray for the matching properties
I've tried to filter them out but not having success, using lodash
You could take a Set for the wanted parents and filter the parent array.
var parents = [{ id: 1, name: 'foo' }, { id: 2, name: 'bar' }],
children = [{ parent_id: 1, prop: 'prop1' }, { parent_id: 3, prop: 'prop3' }],
wanted = new Set(children.map(({ parent_id }) => parent_id)),
result = parents.filter(({ id }) => wanted.has(id));
console.log(result);
You can do so with a combination of Array.filter() and Array.some() in the following way.
const resultingArray = parentArray
.filter(x => childArray.some( y => y.parent_id===x.id));
Check this JS bin
We can use a Set as a lookup table for the parent_id data from the child and then use Array.prototype.filter to filter through the parent entries and use Set#has to check if the id is contained in the Set:
const parentArray = [{id:1, name:'foo'},{id:2, name:'bar'}, {id:4, name:'foo'},{id:6, name:'bar'}]
const childArray = [
{parent_id:1, prop:'prop1'},
{parent_id:2, prop:'prop2'},
{parent_id:3, prop:'prop3'},
{parent_id:4, prop:'prop4'},
{parent_id:5, prop:'prop5'}
];
function findSubSet(){
const lookup = new Set(childArray.map(({parent_id}) => parent_id));
return parentArray.filter(p => lookup.has(p.id));
}
console.log(findSubSet(parentArray, childArray));
You can use reduce & findIndex. In the reduce callback use findIndex to check if there exist same id.If id exist it will return the index & if not then it will return -1. So if index is not -1 then you can push the value to accumulator(acc)
const parentArray = [{
id: 1,
name: 'foo'
}, {
id: 2,
name: 'bar'
}]
const childArray = [{
parent_id: 1,
prop: 'prop1'
},
{
parent_id: 2,
prop: 'prop2'
},
{
parent_id: 3,
prop: 'prop3'
}
]
let filteredData = parentArray.reduce(function(acc, curr) {
let getIndexFromChild = childArray.findIndex(function(item) {
return curr.id === item.parent_id
});
if (getIndexFromChild !== -1) {
acc.push(curr)
}
return acc;
}, []);
console.log(filteredData)
As previously mentioned, your example is unclear, but filtering an array using another array, assuming you want to use the properties id from parentArray and parent_id from childArray, then I would use this:
resultingArray = childArray.filter(c=> parentArray.find(p => p.id === c.parentId);
You can use a mixture of filter and some to get the matching values:
const parentArray = [{id:1, name:'foo'},{id:2, name:'bar'}]
const childArray = [
{parent_id:1, prop:'prop1'},
{parent_id:3, prop:'prop3'}
]
let result = parentArray.filter(i => childArray.some(j => j.parent_id == i.id))
console.log(result)

What happen when i run array.some in array filter

I just learned a new trick to find the same object in 2 array object, it works very well. it uses array.filter and array.some, as code bellow, but I don't understand how filter() can run when some() will return true or false.
const similarity = (arr, values) => arr.filter(item => values.some(m => (m.id === item.id) && (m.name === item.name)));
my input:
let arr1 = [
{
id: 1,
name: "kiet"
},
{
id: 2,
name: 'phan'
},
{
id: 3,
name: 'tuan'
}]
let arr2 = [
{
id: 1,
name: "kiet"
},
{
id: 2,
name: 'haha'
},
{
id: 5,
name: 'tuan'
}
]
my result :
[ { id: 1, name: 'kiet' } ]
You are Filtering the array, then passing this condition inside the some
(m.id === item.id) && (m.name === item.name)
If the id of the second array (here, m is the second array's objects) is equal to the first array's id (here, item is the array's objects) and the name is equal to the first array's name property. If yes then it will return true. So the filter gets a true and if is does, it will return that particular object for which it gets a true
let arr1 = [{ id: 1, name: "kiet" }, { id: 2, name: 'phan' }, { id: 3, name: 'tuan'}]
let arr2 = [ { id: 1, name: "kiet" }, { id: 2, name: 'haha' }, { id: 5, name: 'tuan' } ]
const similarity = (arr, values) => arr.filter(item => values.some(m => (m.id === item.id) && (m.name === item.name)));
console.log(similarity(arr1,arr2))
You get the elements from the array which have the same properties id/name as the values array.
Array#filter needs a (kind of) boolean value and if true or truthy, then the item is taken to the new array.
Array#some checks an item and if the callback returns a truthy value, then it returns true, if not then false.
const
similarity = (array, values) => array.filter(item => values.some(m => m.id === item.id && m.name === item.name)),
arr1 = [ { id: 1, name: "kiet" }, { id: 2, name: 'phan' }, { id: 3, name: 'tuan' }],
arr2 = [ { id: 1, name: "kiet" }, { id: 2, name: 'haha' }, { id: 5, name: 'tuan' }],
result = similarity(arr1, arr2);
console.log(result);
For larger data sets, you could take a Set, this is iterated once with a combined value and checked against for filtering.
const
similarity = (array, values) => {
const
getKey = ({ id, name }) => [id, name].join('|'),
keys = new Set(values.map(getKey));
return array.filter(o => keys.has(getKey(o)));
},
arr1 = [ { id: 1, name: "kiet" }, { id: 2, name: 'phan' }, { id: 3, name: 'tuan' }],
arr2 = [ { id: 1, name: "kiet" }, { id: 2, name: 'haha' }, { id: 5, name: 'tuan' }],
result = similarity(arr1, arr2);
console.log(result);
This is a good technique if you want to check for array intersection.
const vowels = [...'AEIOU'];
const isVowel = x => vowels.some(v => v === x);
const hasVowel = string => [...string].filter(isVowel).length > 0;

javascript add or replace an object by property check inside another array of objects

I want to add or replace an object inside another array.
var arr = [
{uid: 1, name: "bla", description: "cucu"},
{uid: 2, name: "smth else", description: "cucarecu"},
]
here here is an new object:
var mynewObject = {uid: 1, name: "newBlabla", description: "newDesc"};
i am already doing it like:
function addOrReplace (arr, object) {
var index = arr.findIndex(x => object.uid === x.uid);
if (-1 === index) {
arr.push(object);
} else {
arr[index] = object;
}
return arr;
}
but this is very ugly.
is there any way to do it in one line or two?
the original array should remain an array, and the new object should be checked only by property uid.
To achieve the same functionality, yet make it a more condense one-liner, run Array#findIndex and assign its result to the unused parameter idx of the function (effectively overwriting its value, which is undefined by default, or the value, with which the function was called), then use a simple ternary operator to modify the existing object or add to the array and finally return the modified array.
const arr1 = [
{ uid: 1, name: "bla", description: "cucu" },
{ uid: 2, name: "smth else", description: "cucarecu" },
]
const mynewObject1 = { uid: 1, name: "newBlabla", description: "newDesc" };
const arr2 = [
{ uid: 2, name: "smth else", description: "cucarecu" },
]
const mynewObject2 = { uid: 1, name: "newBlabla", description: "newDesc" };
const arr3 = []
const mynewObject3 = { uid: 1, name: "newBlabla", description: "newDesc" };
function addOrReplace (arr, obj, idx) {
return (idx = arr.findIndex(x => obj.uid === x.uid) > -1 ? arr[idx] = obj : arr.push(obj)), arr;
}
console.log(addOrReplace(arr1, mynewObject1));
console.log(addOrReplace(arr2, mynewObject2));
console.log(addOrReplace(arr3, mynewObject3));
Or a bit more concise if you don't need to return the array:
const arr1 = [
{ uid: 1, name: "bla", description: "cucu" },
{ uid: 2, name: "smth else", description: "cucarecu" },
]
const mynewObject1 = { uid: 1, name: "newBlabla", description: "newDesc" };
const arr2 = [
{ uid: 2, name: "smth else", description: "cucarecu" },
]
const mynewObject2 = { uid: 1, name: "newBlabla", description: "newDesc" };
const arr3 = []
const mynewObject3 = { uid: 1, name: "newBlabla", description: "newDesc" };
function addOrReplace (arr, obj, idx) {
idx = arr.findIndex(x => obj.uid === x.uid) > -1 ? arr[idx] = obj : arr.push(obj);
}
addOrReplace(arr1, mynewObject1)
console.log(arr1);
addOrReplace(arr2, mynewObject2)
console.log(arr2);
addOrReplace(arr3, mynewObject3)
console.log(arr3);
const addOrReplace = (arr, obj) => {
arr = arr.filter(el => el.uid !== obj.uid);
arr.push(obj)
return arr;
}

is there a function in lodash to replace matched item

I wonder if there is a simpler method in lodash to replace an item in a JavaScript collection? (Possible duplicate but I did not understand the answer there:)
I looked at their documentation but could not find anything
My code is:
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
// Can following code be reduced to something like _.XX(arr, {id:1}, {id:1, name: "New Name"});
_.each(arr, function(a, idx){
if(a.id === 1){
arr[idx] = {id:1, name: "Person New Name"};
return false;
}
});
_.each(arr, function(a){
document.write(a.name);
});
Update:
The object I'm trying to replace with has many properties like
{id: 1, Prop1: ..., Prop2:..., and so on}
Solution:
Thanks to dfsq but I found a proper solution within lodash that seems to work fine and is pretty neat and I put it in a mixin as well since I've this requirement at many places. JSBin
var update = function(arr, key, newval) {
var match = _.find(arr, key);
if(match)
_.merge(match, newval);
else
arr.push(newval);
};
_.mixin({ '$update': update });
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
_.$update(arr, {id:1}, {id:1, name: "New Val"});
document.write(JSON.stringify(arr));
Faster Solution
As pointed out by #dfsq, following is way faster
var upsert = function (arr, key, newval) {
var match = _.find(arr, key);
if(match){
var index = _.indexOf(arr, _.find(arr, key));
arr.splice(index, 1, newval);
} else {
arr.push(newval);
}
};
In your case all you need to do is to find object in array and use Array.prototype.splice() method, read more details here:
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
// Find item index using _.findIndex (thanks #AJ Richardson for comment)
var index = _.findIndex(arr, {id: 1});
// Replace item at index using native splice
arr.splice(index, 1, {id: 100, name: 'New object.'});
// "console.log" result
document.write(JSON.stringify( arr ));
<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
Seems like the simplest solution would to use ES6's .map or lodash's _.map:
var arr = [{id: 1, name: "Person 1"}, {id: 2, name: "Person 2"}];
// lodash
var newArr = _.map(arr, function(a) {
return a.id === 1 ? {id: 1, name: "Person New Name"} : a;
});
// ES6
var newArr = arr.map(function(a) {
return a.id === 1 ? {id: 1, name: "Person New Name"} : a;
});
This has the nice effect of avoiding mutating the original array.
[ES6] This code works for me.
let result = array.map(item => item.id === updatedItem.id ? updatedItem : item)
function findAndReplace(arr, find, replace) {
let i;
for(i=0; i < arr.length && arr[i].id != find.id; i++) {}
i < arr.length ? arr[i] = replace : arr.push(replace);
}
Now let's test performance for all methods:
// TC's first approach
function first(arr, a, b) {
_.each(arr, function (x, idx) {
if (x.id === a.id) {
arr[idx] = b;
return false;
}
});
}
// solution with merge
function second(arr, a, b) {
const match = _.find(arr, a);
if (match) {
_.merge(match, b);
} else {
arr.push(b);
}
}
// most voted solution
function third(arr, a, b) {
const match = _.find(arr, a);
if (match) {
var index = _.indexOf(arr, _.find(arr, a));
arr.splice(index, 1, b);
} else {
arr.push(b);
}
}
// my approach
function fourth(arr, a, b){
let l;
for(l=0; l < arr.length && arr[l].id != a.id; l++) {}
l < arr.length ? arr[l] = b : arr.push(b);
}
function test(fn, times, el) {
const arr = [], size = 250;
for (let i = 0; i < size; i++) {
arr[i] = {id: i, name: `name_${i}`, test: "test"};
}
let start = Date.now();
_.times(times, () => {
const id = Math.round(Math.random() * size);
const a = {id};
const b = {id, name: `${id}_name`};
fn(arr, a, b);
});
el.innerHTML = Date.now() - start;
}
test(first, 1e5, document.getElementById("first"));
test(second, 1e5, document.getElementById("second"));
test(third, 1e5, document.getElementById("third"));
test(fourth, 1e5, document.getElementById("fourth"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.14.1/lodash.min.js"></script>
<div>
<ol>
<li><b id="first"></b> ms [TC's first approach]</li>
<li><b id="second"></b> ms [solution with merge]</li>
<li><b id="third"></b> ms [most voted solution]</li>
<li><b id="fourth"></b> ms [my approach]</li>
</ol>
<div>
If you're just trying to replace one property, lodash _.find and _.set should be enough:
var arr = [{id: 1, name: "Person 1"}, {id: 2, name: "Person 2"}];
_.set(_.find(arr, {id: 1}), 'name', 'New Person');
You can also use findIndex and pick to achieve the same result:
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
var data = {id: 2, name: 'Person 2 (updated)'};
var index = _.findIndex(arr, _.pick(data, 'id'));
if( index !== -1) {
arr.splice(index, 1, data);
} else {
arr.push(data);
}
As the time passes you should embrace a more functional approach in which you should avoid data mutations and write small, single responsibility functions. With the ECMAScript 6 standard, you can enjoy functional programming paradigm in JavaScript with the provided map, filter and reduce methods. You don't need another lodash, underscore or what else to do most basic things.
Down below I have included some proposed solutions to this problem in order to show how this problem can be solved using different language features:
Using ES6 map:
const replace = predicate => replacement => element =>
predicate(element) ? replacement : element
const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
const predicate = element => element.id === 1
const replacement = { id: 100, name: 'New object.' }
const result = arr.map(replace (predicate) (replacement))
console.log(result)
Recursive version - equivalent of mapping:
Requires destructuring and array spread.
const replace = predicate => replacement =>
{
const traverse = ([head, ...tail]) =>
head
? [predicate(head) ? replacement : head, ...tail]
: []
return traverse
}
const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
const predicate = element => element.id === 1
const replacement = { id: 100, name: 'New object.' }
const result = replace (predicate) (replacement) (arr)
console.log(result)
When the final array's order is not important you can use an object as a HashMap data structure. Very handy if you already have keyed collection as an object - otherwise you have to change your representation first.
Requires object rest spread, computed property names and Object.entries.
const replace = key => ({id, ...values}) => hashMap =>
({
...hashMap, //original HashMap
[key]: undefined, //delete the replaced value
[id]: values //assign replacement
})
// HashMap <-> array conversion
const toHashMapById = array =>
array.reduce(
(acc, { id, ...values }) =>
({ ...acc, [id]: values })
, {})
const toArrayById = hashMap =>
Object.entries(hashMap)
.filter( // filter out undefined values
([_, value]) => value
)
.map(
([id, values]) => ({ id, ...values })
)
const arr = [ { id: 1, name: "Person 1" }, { id:2, name:"Person 2" } ];
const replaceKey = 1
const replacement = { id: 100, name: 'New object.' }
// Create a HashMap from the array, treating id properties as keys
const hashMap = toHashMapById(arr)
console.log(hashMap)
// Result of replacement - notice an undefined value for replaced key
const resultHashMap = replace (replaceKey) (replacement) (hashMap)
console.log(resultHashMap)
// Final result of conversion from the HashMap to an array
const result = toArrayById (resultHashMap)
console.log(result)
Came across this as well and did it simply that way.
const persons = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
const updatedPerson = {id: 1, name: "new Person Name"}
const updatedPersons = persons.map(person => (
person.id === updated.id
? updatedPerson
: person
))
If wanted we can generalize it
const replaceWhere = (list, predicate, replacement) => {
return list.map(item => predicate(item) ? replacement : item)
}
replaceWhere(persons, person => person.id === updatedPerson.id, updatedPerson)
var arr= [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
var index = _.findIndex(arr, {id: 1});
arr[index] = {id: 100, name: 'xyz'}
If the insertion point of the new object does not need to match the previous object's index then the simplest way to do this with lodash is by using _.reject and then pushing new values in to the array:
var arr = [
{ id: 1, name: "Person 1" },
{ id: 2, name: "Person 2" }
];
arr = _.reject(arr, { id: 1 });
arr.push({ id: 1, name: "New Val" });
// result will be: [{ id: 2, name: "Person 2" }, { id: 1, name: "New Val" }]
If you have multiple values that you want to replace in one pass, you can do the following (written in non-ES6 format):
var arr = [
{ id: 1, name: "Person 1" },
{ id: 2, name: "Person 2" },
{ id: 3, name: "Person 3" }
];
idsToReplace = [2, 3];
arr = _.reject(arr, function(o) { return idsToReplace.indexOf(o.id) > -1; });
arr.push({ id: 3, name: "New Person 3" });
arr.push({ id: 2, name: "New Person 2" });
// result will be: [{ id: 1, name: "Person 1" }, { id: 3, name: "New Person 3" }, { id: 2, name: "New Person 2" }]
Using lodash unionWith function, you can accomplish a simple upsert to an object. The documentation states that if there is a match, it will use the first array. Wrap your updated object in [ ] (array) and put it as the first array of the union function. Simply specify your matching logic and if found it will replace it and if not it will add it
Example:
let contacts = [
{type: 'email', desc: 'work', primary: true, value: 'email prim'},
{type: 'phone', desc: 'cell', primary: true, value:'phone prim'},
{type: 'phone', desc: 'cell', primary: false,value:'phone secondary'},
{type: 'email', desc: 'cell', primary: false,value:'email secondary'}
]
// Update contacts because found a match
_.unionWith([{type: 'email', desc: 'work', primary: true, value: 'email updated'}], contacts, (l, r) => l.type == r.type && l.primary == r.primary)
// Add to contacts - no match found
_.unionWith([{type: 'fax', desc: 'work', primary: true, value: 'fax added'}], contacts, (l, r) => l.type == r.type && l.primary == r.primary)
If you want to make a function and keep it "lodash-ey", you can make a wrapper function that works with callbacks. It makes the function more general use.
To write this try something like
function findAllAndReplace(array, replacement, callback){
return array.map( element => callback(element) ? replacement : element )
}
To find and replace by key, just make your callback very simple. (itemInArray) => itemInArray.keyOnItem
But if you want more advanced functionality you can incorporate it with barely any extra effort. Here are some examples.
(Simple) Find the item with id 2, replace it to have an id: 7
const items = [{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}]
findAllAndReplace( items, {id: 7}, item => item.id === 2 )
(Slightly More Complex) Find 28 year old named John, and replace him with a 28 year old named Jon
const people = [
{
name: "John",
age: 20
},
{
name: "John",
age: 28
},
{
name: "Jim",
age: 28
},
]
findAllAndReplace(
people, // all the people
{ name: "Jon", age: 28 }, // Replacement value
(person) => person.name === "jon" && person.age === 21 // callback function
)
Also, the method above will find all instances that match and replace them, but if you just want to do it for one you could do something like below.
function findOneAndReplace(array, replacement, callback){
const splitIndex = array.findIndex(callback)
// This if statement can be ommitted, but might
// be handy depending on your use case
if(splitIndex < 0){
throw new Error("Swap Element not found")
}
const leadingTerms = array.slice(0, splitIndex)
const trailingTerms = array.slice(splitIndex + 1, array.length)
return [...leadingTerms, replacement, ...trailingTerms]
)
note: It might be useful to make your function break if it doesn't find a matching element, but if you don't want that feature you can cut those lines of code out.
Not bad variant too)
var arr = [{id: 1, name: "Person 1"}, {id: 2, name: "Person 2"}];
var id = 1; //id to find
arr[_.find(arr, {id: id})].name = 'New Person';
If you're looking for a way to immutably change the collection (as I was when I found your question), you might take a look at immutability-helper, a library forked from the original React util. In your case, you would accomplish what you mentioned via the following:
var update = require('immutability-helper')
var arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}]
var newArray = update(arr, { 0: { name: { $set: 'New Name' } } })
//=> [{id: 1, name: "New Name"}, {id:2, name:"Person 2"}]
You can do it without using lodash.
let arr = [{id: 1, name: "Person 1"}, {id: 2, name: "Person 2"}];
let newObj = {id: 1, name: "new Person"}
/*Add new prototype function on Array class*/
Array.prototype._replaceObj = function(newObj, key) {
return this.map(obj => (obj[key] === newObj[key] ? newObj : obj));
};
/*return [{id: 1, name: "new Person"}, {id: 2, name: "Person 2"}]*/
arr._replaceObj(newObj, "id")
Immutable, suitable for ReactJS:
Assume:
cosnt arr = [{id: 1, name: "Person 1"}, {id:2, name:"Person 2"}];
The updated item is the second and name is changed to Special Person:
const updatedItem = {id:2, name:"Special Person"};
Hint: the lodash has useful tools but now we have some of them on Ecmascript6+, so I just use map function that is existed on both of lodash and ecmascript6+:
const newArr = arr.map(item => item.id === 2 ? updatedItem : item);

Categories