How to remove duplicates objects in array and the original value based on 2 properties
This what i do but this return the original
const rooms = [
{
room_rate_type_id: 202,
price: 200
},
{
room_rate_type_id: 202,
price: 200
},
{
room_rate_type_id: 202,
price: 189
},
{
room_rate_type_id: 190,
price: 200
}
];
let result = rooms.filter((e, i) => {
return rooms.findIndex((x) => {
return x.room_rate_type_id == e.room_rate_type_id && x.price == e.price;}) == i;
});
console.log(result);
i want the result to be only
{
room_rate_type_id: 202,
price: 189
},
{
room_rate_type_id: 190,
price: 200
}
I presume you wish to find the cheapest price for each room_rate_type_id, we can do this using Array.reduce().
We get the cheapest price for each rate type id by looping over each entry and replacing the value for each rate id if the entry price is lower than the current lowest value:
const rooms = [ { room_rate_type_id: 202, price: 200 }, { room_rate_type_id: 202, price: 200 }, { room_rate_type_id: 202, price: 189 }, { room_rate_type_id: 190, price: 200 } ];
const result = Object.values(rooms.reduce((acc, cur) => {
if (!acc[cur.room_rate_type_id] || acc[cur.room_rate_type_id].price > cur.price) acc[cur.room_rate_type_id] = cur;
return acc;
}, {}));
console.log('Result:', result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I'd like to create result array and use rooms.forEach(...) instead of rooms.filter(...) to iterate through the items in rooms and on the every iteration we can check if there's an object with the same room_rate_type_id and price property values. To check the object existence in the result array I'm using result.findIndex(...). If this method returns a value 0 or greater than 0, that means we already have item with these values and no need to add it to the result array, otherwise result doesn't contain similar object and we need to add. Here's the example how I do it:
const rooms = [
{
room_rate_type_id: 202,
price: 200
},
{
room_rate_type_id: 202,
price: 200
},
{
room_rate_type_id: 202,
price: 189
},
{
room_rate_type_id: 190,
price: 200
}
];
const result = [];
rooms.forEach(item => {
if (result.findIndex(x => x.room_rate_id === item.room_rate_id && x.price === item.price) < 0) {
result.push(item);
}
});
console.log(result)
You could take a Map and filter the values.
const
getKey = o => ['room_rate_type_id', 'price'].map(k => o[k]).join('|'),
rooms = [{ room_rate_type_id: 202, price: 200 }, { room_rate_type_id: 202, price: 200 }, { room_rate_type_id: 202, price: 189 }, { room_rate_type_id: 190, price: 200 }],
result = [
...rooms
.reduce(
(m, o) => (k => m.set(k, !m.has(k) && o))(getKey(o)),
new Map
)
.values()
]
.filter(Boolean);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }