Objects:[
{id:'a',
owner: 'b',
products:[{productId:'a1',name:'b1'},{productId:'a2',name:'b2'}]
date: '2-2'},
{id:'e',
owner: 'f',
products:[{productId:'a3',name:'b3'},{productId:'a4',name:'b4'}]
date: '1-1'}
{id:'g',
owner: 'y',
products:[{productId:'a4',name:'b3'},{productId:'a7',name:'b9'}]
date: '1-3'}
]
Result:
[{id:'e',
owner: 'f',
products:[{productId:'a3',name:'b3'}]
date: '1-1'}
{id:'g',
owner: 'y',
products:[{productId:'a4',name:'b3'}]
date: '1-3'}]
In above example, how do I get the second object by the value of name:'b3'? and get rid of this part {productId:'a4',name:'b4'} The name is an attribute of products array and products is an attribute of objects array. I'll appreciate if someone can help me out.
CodePudding user response:
You could practically achieve the result you desire in 2 steps, first by using Array.find
to find the object. And then by using Array.filter
to filter out all other products
. Like this:
const objects = [
{
id: 'a',
owner: 'b',
products: [
{ productId: 'a1', name: 'b1' },
{ productId: 'a2', name: 'b2' },
],
date: '2-2',
},
{
id: 'e',
owner: 'f',
products: [
{ productId: 'a3', name: 'b3' },
{ productId: 'a4', name: 'b4' },
],
date: '1-1',
},
];
const searchVal = 'b3';
let result = objects.find((obj) => obj.products.some((p) => p.name === searchVal));
if (result) {
result = {
...result,
products: result.products.filter((r) => r.name === searchVal)
}
}
console.log(result);
If you're planning using this approach on multiple different places in your code, then you could also create a function to handle it for you:
const objects = [
{
id: 'a',
owner: 'b',
products: [
{ productId: 'a1', name: 'b1' },
{ productId: 'a2', name: 'b2' },
],
date: '2-2',
},
{
id: 'e',
owner: 'f',
products: [
{ productId: 'a3', name: 'b3' },
{ productId: 'a4', name: 'b4' },
],
date: '1-1',
},
];
const getObjectWithFilteredProducts = (objArr, searchVal) => {
let result = objects.find((obj) => obj.products.some((p) => p.name === searchVal));
if (result) {
result = {
...result,
products: result.products.filter((r) => r.name === searchVal),
};
}
return result;
};
console.log(getObjectWithFilteredProducts(objects, 'b3'));
EDIT
If you want an array as your result, you could do it like this:
const objects = [
{
id: 'a',
owner: 'b',
products: [
{ productId: 'a1', name: 'b1' },
{ productId: 'a2', name: 'b2' },
],
date: '2-2',
},
{
id: 'e',
owner: 'f',
products: [
{ productId: 'a3', name: 'b3' },
{ productId: 'a4', name: 'b4' },
],
date: '1-1',
},
];
const searchVal = 'b3';
const result = objects.reduce((acc, obj) => {
if (obj.products.some((p) => p.name === searchVal)) {
return [
...acc,
{
...obj,
products: obj.products.filter((p) => p.name === searchVal),
},
];
}
return acc;
}, []);
console.log(result);
CodePudding user response:
I guess you can do something like this. Your existing filter will find the top level object that contains a product with the correct name. If that object is found, you can then filter the array of products, matching on searchValue
const tempObjects = Objects.filter((obj) => hasProductsByName(obj.products))
let products = []
temp.forEach(
(obj) =>
(products = products.concat(
obj.products.filter((product) => product.name === searchValue)
))
)
products
should now contain all products matching the searchValue