Compare Javascript Object field with another Object field [duplicate] - javascript

This question already has answers here:
Merge two array of objects based on a key
(23 answers)
Closed last year.
I have two Objects one of them has the Store Name and the other object has the Price for an item along with the Store ID on both objects. Such as;
obj1 = [
{id: 1,name: "Store1"},
{id: 2,name: "Store2"},
{id: 3,name: "Store3"}
];
obj2= [
{ id: 1, price: 100 },
{ id: 2, price: 200 },
{ id: 3, price: 300 }
];
What I want to achieve is that compare obj1 id with obj2 id if they are the same get the price and the store name from the same id. What is the best way to achieve this? I have been trying to use Array.map or filter but can't really make it work. Thank you!

You can use map & find
const obj1 = [{
id: 1,
name: "Store1"
},
{
id: 2,
name: "Store2"
},
{
id: 3,
name: "Store3"
},
{
id: 4,
name: "Store3"
}
];
const obj2 = [{
id: 1,
price: 100
},
{
id: 2,
price: 200
},
{
id: 3,
price: 300
}
];
const newData = obj1.map((item, index) => {
return {
...item,
// if the item exist in obj2 then get the price else assign empty string
price: obj2.find(elem => elem.id === item.id) ? .price || ''
}
});
console.log(newData)

Related

Replace/Update The Existing Array of Object that Matches the Incoming Array

I'm trying to find and replace the array if an incoming arrays matches the existing one but unfortunately, I'm stucked with the some
Here's my existing array.
let existingData = [{
id: 1,
product: 'Soap',
price: '$2'
},{
id: 2,
product: 'Sofa',
price: '$30'
},{
id: 3,
product: 'Chair',
price: '$45'
}]
And here's my incoming array.
const updateData = [{
id: 1,
product: 'Soap',
price: '$3'
},{
id: 2,
product: 'Sofa',
price: '$35'
}]
So far, I saw the foreach but unfortunately, I'm not sure how can I use it if the term is an array. But I get stuck and I can't proceed.
const updateData = [{
id: 1,
product: 'Soap',
price: '$3'
},{
id: 2,
product: 'Sofa',
price: '$35'
}]
existingData.forEach(d=>{
if(d.id === ??? how can I match this to the incoming array?)
// if matches, then update the existing data with the updated one.
})
And the expected result must be something like this:
let existingData = [{
id: 1,
product: 'Soap',
price: '$3'
},{
id: 2,
product: 'Sofa',
price: '$35'
},{
id: 3,
product: 'Chair',
price: '$45'
}]
If in some cases, the data is not present in the existingData, then the incoming array will just add simply in the existing array.
Please help how can I achieve it and if there's a better and cleaner way to do this, please let me know. Thank you!
You can easily achieve this result using forEach and find
let existingData = [{
id: 1,
product: "Soap",
price: "$2",
},
{
id: 2,
product: "Sofa",
price: "$30",
},
{
id: 3,
product: "Chair",
price: "$45",
},
];
const updateData = [{
id: 1,
product: "Soap",
price: "$3",
},
{
id: 2,
product: "Sofa",
price: "$35",
},
];
updateData.forEach((obj) => {
let isExist = existingData.find((o) => o.id === obj.id);
if (isExist) {
isExist.price = obj.price;
isExist.product = obj.product;
}
});
console.log(existingData);
If there are multiple properties that need to be updated then you can use for..in loop over the updated object and replace the prop in the existing property.
updateData.forEach((obj) => {
let isExist = existingData.find((o) => o.id === obj.id);
if (isExist) {
for (let prop in obj) {
isExist[prop] = obj[prop];
}
}
});
If you want to add the data if it doesn't exist in the existing array then you need to push it into existingData array.
let existingData = [{
id: 1,
product: "Soap",
price: "$2",
},
{
id: 2,
product: "Sofa",
price: "$30",
},
{
id: 3,
product: "Chair",
price: "$45",
},
];
const updateData = [{
id: 1,
product: "Soap",
price: "$3",
},
{
id: 2,
product: "Sofa",
price: "$35",
},
{
id: 6,
product: "Sofa",
price: "$135",
},
];
updateData.forEach((obj) => {
let isExist = existingData.find((o) => o.id === obj.id);
if (isExist) {
for (let prop in obj) {
isExist[prop] = obj[prop];
}
} else {
existingData.push(obj);
}
});
console.log(existingData);
existingData.forEach(existingItem => {
let item = updatedDate.find(u => u.id === existingItem.id);
if(item){
existingItem.product = item.product;
existingItem.price= item.price;
}
});
Given your existingData and updateData, you can quite simply do something like this:
// form a temporary object mapping updated objects' ids to the new ids
const updateDataByKeys = Object.fromEntries(updateData.map(e => [e.id, e]));
// map through `existingData`, replacing old entries with updated where they
// exist in the above temporary object, using the old object if they don't.
const newData = existingData.map(e => updateDataByKeys[e.id] || e);
Creating the temporary object should make this approach quite a bit faster than approaches using .find() on updateData.
If you need to merge the data from updateData into the existing objects, you could do
const newData = existingData.map(
e => updateDataByKeys[e.id] ? ({...e, ...updateDataByKeys[e.id]}) : e
);
EDIT: Based on comments, if you also need to add new objects from updateData:
// form a temporary object mapping updated objects' ids to the new ids
const updateDataByKeys = Object.fromEntries(updateData.map(e => [e.id, e]));
// Map through `existingData`, replacing old entries with updated where they
// exist in the above temporary object, using the old object if they don't.
// When using an update object, removes it from the mapping; the left-over
// new data (which had no ID in the old data) are then concatenated to the
// list.
const newData = existingData.map(e => {
if(updateDataByKeys[e.id]) {
const val = updateDataByKeys[e.id];
delete updateDataByKeys[e.id];
return val;
}
return e;
}).concat(Object.values(updateDataByKeys));

Find Duplicate Object in List and Add Parameters

I am trying to find duplicate objects in a list of objects and add new parameters to the duplicate one.
Below snipped code is what I implemented so far. The problem is that it adds desired parameters to every object in the list.
const list = [{
id: 1,
name: 'test1'
},
{
id: 2,
name: 'test2'
},
{
id: 3,
name: 'test3'
},
{
id: 2,
name: 'test2'
}
];
const newList = list.reduce(
(unique, item) => (unique.includes(item) ? unique : [...unique, {
...item,
duplicated: true,
name: `${item.name}_${item.id}`
}]), []
);
console.log(newList);
Since there are two duplicate objects by id, the duplicated one should have duplicated and new name parameters. What part is wrong in my implementation?
By using findIndex method:
const list = [{
id: 1,
name: 'test1'
},
{
id: 2,
name: 'test2'
},
{
id: 3,
name: 'test3'
},
{
id: 2,
name: 'test2'
}
];
const newList = list.reduce(
(unique, item) => (unique.findIndex(x => x.id === item.id) > -1 ? [...unique, {
...item,
duplicated: true,
name: `${item.name}_${item.id}`
}] : [...unique, item]), []);
console.log(newList);
It can be written simply:
const
list = [
{ id: 1, name: 'test1' },
{ id: 2, name: 'test2' },
{ id: 3, name: 'test3' },
{ id: 2, name: 'test2' }
],
uniqueList = list.reduce((arr, { id, name }) =>
arr.concat({
id,
name,
...arr.some(item => id === item.id) && { duplicate: true, name: `${name}_${id}` }
}), []);
console.log(uniqueList);
The problem was that when you called includes you were actually looking for an object whose pointer exists in the array.
In order to find an object which has property are the same as a requested property, you have no choice but to use functions such as some or every that is different from includes - you can send them a callback and not just an object.

Remove attribute from JSON objects in a array [duplicate]

This question already has answers here:
How do I remove a property from a JavaScript object?
(37 answers)
Loop through an array in JavaScript
(46 answers)
Closed 4 years ago.
I have an array of json objects.
var user =[ { id: 1, name: 'linto', img: 'car' },
{ id: 2, name: 'shinto', img: 'ball' },
{ id: 3, name: 'hany', img: 'kite' } ]
From this is want to remove attribute img from all the elements of the array, so the output looks like this.
var user =[ { id: 1, name: 'linto' },
{ id: 2, name: 'shinto' },
{ id: 3, name: 'hany' } ]
Is there a way to do this in java script.
You can use .map() with Object Destructuring:
let data =[
{ id: 1, name: 'linto', img: 'car' },
{ id: 2, name: 'shinto', img: 'ball' },
{ id: 3, name: 'hany', img: 'kite' }
];
let result = data.map(({img, ...rest}) => rest);
console.log(result);
Array.prototype.map()
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
You can use map() in the following way:
var user =[ { id: 1, name: 'linto', img: 'car' },
{ id: 2, name: 'shinto', img: 'ball' },
{ id: 3, name: 'hany', img: 'kite' } ]
user = user.map(u => ({id: u.id, name: u.name}));
console.log(user);

Lodash check if any object in array contains id match from another array

I have one user array like:
var users = [{
id: 1,
name: 'ABC',
isDisplay: true
}, {
id: 2,
name: 'XYZ',
isDisplay: true
}, {
id: 3,
name: 'JKL',
isDisplay: true
}];
And another array selectedUsers which contains some object from above array like:
var selectedUsers = [{
id: 1,
name: 'ABC'
},
{
id: 3,
name: 'JKL'
}];
Not with lodash, i want to indentify which object are present in second array with matching its ID.
_.each(users, (_u) => {
if(selectedUsers.includes(_u)) {
_u.isDisplay = false;
} else {
_u.isDisplay = true;
}
});
I have tried to match whole object with includes but it dint work, because i am using angularjs, so angular put some $$hashkey with object, so it will not match, Is there any other way to do this.
var users = [{
id: 1,
name: 'ABC',
isDisplay: true
}, {
id: 2,
name: 'XYZ',
isDisplay: true
}, {
id: 3,
name: 'JKL',
isDisplay: true
}];
var selectedUsers = [{
id: 1,
name: 'ABC'
},
{
id: 3,
name: 'JKL'
}];
var intersection = _.intersectionBy(users, selectedUsers, 'id');
console.log(intersection);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.13.1/lodash.js"></script>
Create a Set of selected ids (selectedUsersIds). Iterate the users array with Array#forEach, assign the value of isDisplay by checking if the id exists in the selectedUsersIds set:
const users = [{"id":1,"name":"ABC","isDisplay":true},{"id":2,"name":"XYZ","isDisplay":true},{"id":3,"name":"JKL","isDisplay":true}];
const selectedUsers = [{"id":1,"name":"ABC"},{"id":3,"name":"JKL"}];
const selectedUsersIds = new Set(selectedUsers.map(({ id }) => id));
users.forEach((u) => u.isDisplay = selectedUsersIds.has(u.id));
console.log(users);

How to find array element by reference in order to merge array with typescript? [duplicate]

This question already has answers here:
Javascript Array Concat not working. Why?
(7 answers)
Closed 6 years ago.
I have an object I want to unflatten and merge certain subElements by the id of child objects. So that instead of 4 objects with duplicate values, I will only have two, and the two will then have a merged subElement array.
So these my interfaces and test cases:
interface ISubElement {
id: number;
price: number;
}
interface IElements {
id: number;
subElements: ISubElement[];
}
interface IElementCollection {
elements: IElements[];
}
const rawObject: IElementCollection = {
elements: [
{
id: 1,
subElements: [
{id: 111, price: 500},
],
},
{
id: 1,
subElements: [
{id: 222, price: 1000},
],
},
{
id: 1,
subElements: [
{id: 333, price: 1500},
],
},
{
id: 2,
subElements: [
{id: 123, price: 700},
],
},
],
};
const expected: IElementCollection = {
elements: [
{
id: 1,
subElements: [
{id: 111, price: 500},
{id: 222, price: 1000},
{id: 333, price: 1500},
],
},
{
id: 2,
subElements: [
{id: 123, price: 700},
],
},
],
};
This is the function I came up with:
const mergeSubElements = (rawCollection: IElementCollection) => {
let mergedCollection: IElementCollection = <IElementCollection> {
elements: [],
};
rawCollection.elements.forEach((element: IElements) => {
console.log('iterating', JSON.stringify(element, null, 4));
const existing = mergedCollection.elements.find((existingElement: IElements) => {
return existingElement.id === element.id;
});
if (existing) {
console.log('should add to existing', JSON.stringify(existing, null, 4));
existing.subElements.concat(element.subElements);
return;
}
mergedCollection.elements.push(element);
});
console.log(JSON.stringify(mergedCollection, null, 4));
return mergedCollection;
};
It seems my problem is that array.prototype.find only gets me the object as value and not as a reference, as even though I concat fields, they won't be inside the mergedCollecton.
How do I find an object in typescript rather per reference than value?
Here's my mocha test case:
describe('it should merge subElements for each element by id', () => {
it('this shall merge', () => {
return expect(mergeSubElements(rawObject)).to.deep.equal(expected);
});
});
existing.subElements = existing.subElements.concat(element.subElements);
It's not that find won't return an object by reference, the issue was with concat:
The concat() method is used to merge two or more arrays. This method
does not change the existing arrays, but instead returns a new array.
var arr3 = arr1.concat(arr2);

Categories

Resources