Reputation: 1151
I have an object array that looks something like this:
let products = [
{
"id": 7,
"name": "product 1",
"description": "description product 1",
"images": [
{
"id": 1,
"path": "image1-product1.jpeg",
},
{
"id": 2,
"path": "image2-product1.jpeg",
}
]
},
{
"id": 20,
"name": "product 2",
"description": "description product 2",
"images": [
{
"id": 3,
"path": "image1-product2.jpeg",
},
{
"id": 4,
"path": "image2-product2.jpeg",
}
]
}
]
Each product has an image array, I need to compare this image arrangement, with one that I will receive as a parameter and that will look exactly like one of them, to know which product it belongs to and return that product. for example if I receive this array:
[
{
"id": 3,
"path": "image1-product2.jpeg",
},
{
"id": 4,
"path": "image2-product2.jpeg",
}
]
equals the images array of product 2, so how can I compare these and return that product?
Upvotes: 1
Views: 79
Reputation: 51826
If comparing by the id
is sufficient, using Array.prototype.every()
is a lot more efficient than using JSON.stringify()
:
const productHasImages = images => product => (
product.images.length === images.length &&
product.images.every(
(image, i) => image.id === images[i].id
)
);
const products = [{ id: 7, name: 'product 1', description: 'description product 1', images: [{ id: 1, path: 'image1-product1.jpeg' }, { id: 2, path: 'image2-product1.jpeg' }] }, { id: 20, name: 'product 2', description: 'description product 2', images: [{ id: 3, path: 'image1-product2.jpeg' }, { id: 4, path: 'image2-product2.jpeg' }] }];
const images = [{ id: 3, path: 'image1-product2.jpeg' }, { id: 4, path: 'image2-product2.jpeg' }];
const product = products.find(productHasImages(images));
console.log(product);
If you want to match regardless of order and you need to compare multiple properties, then you'll need to be a bit more clever by initializing a Map
keyed by id
in the closure:
const productHasImages = images => {
const map = new Map(
images.map(image => [image.id, image])
);
return product => (
product.images.length === images.length &&
product.images.every(
({ id, path }) => {
const image = map.get(id);
if (!image) return false;
// compare other properties here
return image.path === path;
}
)
);
};
const products = [{ id: 7, name: 'product 1', description: 'description product 1', images: [{ id: 1, path: 'image1-product1.jpeg' }, { id: 2, path: 'image2-product1.jpeg' }] }, { id: 20, name: 'product 2', description: 'description product 2', images: [{ id: 3, path: 'image1-product2.jpeg' }, { id: 4, path: 'image2-product2.jpeg' }] }];
// in different order
const images = [{ id: 4, path: 'image2-product2.jpeg' }, { id: 3, path: 'image1-product2.jpeg' }];
const product = products.find(productHasImages(images));
console.log(product);
Upvotes: 2
Reputation: 2828
If order does not matter and the assumption can be made that all the id and path match and need to be exact... Then you can just compare the stringify of each array. If you need to more relaxed comapre then you have to loop even more into the arrays and compare individual values.
let products = [
{
"id": 7,
"name": "product 1",
"description": "description product 1",
"images": [
{
"id": 1,
"path": "image1-product1.jpeg",
},
{
"id": 2,
"path": "image2-product1.jpeg",
}
]
},
{
"id": 20,
"name": "product 2",
"description": "description product 2",
"images": [
{
"id": 3,
"path": "image1-product2.jpeg",
},
{
"id": 4,
"path": "image2-product2.jpeg",
}
]
}
]
let incoming = [
{
"id": 3,
"path": "image1-product2.jpeg",
},
{
"id": 4,
"path": "image2-product2.jpeg",
}
]
let result = null
result = products.find(product => {
return JSON.stringify(product.images) === JSON.stringify(incoming)
})
console.log(result)
Upvotes: 2
Reputation: 4406
If I understood right. You will get an object containing an id and a image. This object is inside one of the products images somewhere, and you want to find/return the product that holds this image?
If so, you can combine the .find array prototype to find the object passing the condition (one of the images being the one you provide)
let products = [{
"id": 7,
"name": "product 1",
"description": "description product 1",
"images": [{
"id": 1,
"path": "image1-product1.jpeg",
},
{
"id": 2,
"path": "image2-product1.jpeg",
}
]
},
{
"id": 20,
"name": "product 2",
"description": "description product 2",
"images": [{
"id": 3,
"path": "image1-product2.jpeg",
},
{
"id": 4,
"path": "image2-product2.jpeg",
}
]
}
]
const compare = (imageObjToFind) => {
return products.find(product => product.images.find(image => JSON.stringify(image) === JSON.stringify(imageObjToFind)))
}
const IwantToCompareThis = {
"id": 4,
"path": "image2-product2.jpeg",
}
console.log(compare(IwantToCompareThis))
Upvotes: 0