How to group nested array of objects in js - javascript

I have a nested array of objects. I'm trying to group product objects that have the same value.
Each objects has a vendor property containing an email. I am trying to group the objects by matching vendor email
This is how my database looks like:
[
{
_id: "622d70a49bd88b1599026318",
products: [
{
_id: "6223186e2278d4e502f5264a",
title: "Product number 1",
price: 600,
cartQuantity: 1,
vendor: {email: "vendor1#gmail.com"}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
}
]
}]
I am trying to do it with the reduce method but the problem is with using map inside the reduce. It repeats the object many times. I am also unable to get the grouped objects.
const groupedMap = db.reduce(
(entryMap, e) => e.products.map((product) => entryMap.set(product.vendor.email, [...entryMap.get(product)||[], product])),
new Map()
);
The above code output is:
My expectation is:
[0: {"vendor1#gmail.com" => Array(1)}
key: "vendor1#gmail.com"
value: [{_id: '6223186e2278d4e502f5264a', title: 'Product number 1', price: 600, cartQuantity: 1, vendor: {email: "vendor1#gmail.com"}}],
1: {"vendor2#gmail.com" => Array(2)}
key: "vendor2#gmail.com"
value: [{_id: '6223186e2278d4e502f5264a', title: 'Product number 1', price: 600, cartQuantity: 1, vendor: {email: "vendor2#gmail.com"}},
{_id: '6223186e2278d4e502f5264a', title: 'Product number 1', price: 600, cartQuantity: 1, vendor: {email:"vendor2#gmail.com"}}
]
]

Loop through each item in the array and see if the vendor email exists as a key already in a dictionary, if it exists push it to that array, otherwise set the value of the vendor email key equal to an array with the current item in it
See code below
const data = [{
_id: "622d70a49bd88b1599026318",
products: [{
_id: "6223186e2278d4e502f5264a",
title: "Product number 1",
price: 600,
cartQuantity: 1,
vendor: {
email: "vendor1#gmail.com"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
}
]
}];
const mapped = {};
data[0].products.forEach(item => {
if (item.vendor.email in mapped) return mapped[item.vendor.email].push(item);
mapped[item.vendor.email] = [item];
});
const expectedFormat = Object.keys(mapped).map(key => {
const o = {};
o[key] = mapped[key];
return o;
});
console.log(expectedFormat)

try to make an object where key is the value you group by. the next step is foreach in which you check each object in the array, whether the value you are looking for is in the object made - if not, then you filter the array by searched value and add the result to your object

Related

ReactJs How to map field of an array into a new array?

I'm new to javascript and react and working on my first mini project but I cannot figure out how to solve this.
In each "Order" model I have this array field called "orderItems" which holds an array of product models and within each product model there's a field called "shop". I want to get the "shop" value for all the products in orderItems and add it into a new array in "Order" model
Here is my schema:
{
orderItems: [
{
name: 'abc',
quantity: 1,
shop: 'abc',
image: '/images/cake.jpg',
price: 50,
_id: new ObjectId("62dbb03e90c4ca14ee3e06fd")
},
{
name: 'def',
quantity: 1,
shop: 'def',
image: '/images/cake.jpg',
price: 50,
_id: new ObjectId("62dbb03e90c4ca14ee3e06fd")
}
],
sellers: [],
shippingAddress: {
fullName: '123',
address: '123',
city: '123',
postalCode: '123',
country: '123'
},
paymentMethod: 'Paypal',
itemsPrice: 50,
shippingPrice: 10,
totalPrice: 60,
buyer: new ObjectId("62d6e48d8cd5cd2e62f6aeae"),
_id: new ObjectId("62dbcf88cf1bc8fc7b85cc0b"),
__v: 0
}
So I want to get 'abc', and 'def' from orderItems array and fill it in the sellers array. I can get the values but how do I fill it into the sellers array in the same model?
this is my api code
orderRouter.post(
'/', isAuth, expressAsyncHandler(async(req, res) => {
const newOrder = new Order({
orderItems: req.body.orderItems.map((x) => ({ ...x, product: x._id })),
shippingAddress: req.body.shippingAddress,
paymentMethod: req.body.paymentMethod,
itemsPrice: req.body.itemsPrice,
shippingPrice: req.body.shippingPrice,
totalPrice: req.body.totalPrice,
buyer: req.user._id,
sellers: [],
});
const order = await newOrder.save();
})
);
I tried using a loop and then order.sellers.push(order.orderItems[i].shop) and then saving again but its not updating in my database & in local storage the _id field was pushed into the array instead of shop
Step by step:
Declare a separated const orderItems above const newOrder.
Extract const sellers using a Set. You can also do it with an array or even an object, but Set will filter out duplicates automatically.
The create the order, using the 2 consts above, and remember to turn the Set into an array.
Should look something like this:
const orderItems = req.body.orderItems.map((x) => ({ ...x, product: x._id }));
const sellers = [...new Set(orderItems.map(x => x.shop))];
const newOrder = new Order({
orderItems,
sellers: [...sellers],
shippingAddress: req.body.shippingAddress,
paymentMethod: req.body.paymentMethod,
itemsPrice: req.body.itemsPrice,
shippingPrice: req.body.shippingPrice,
totalPrice: req.body.totalPrice,
buyer: req.user._id,
});
And here's a working example:
const orderItems = [{
name: 'P1',
quantity: 1,
shop: 'S1',
image: '/images/p1.jpg',
price: 50,
_id: '62dbb03e90c4ca14ee3e06fa',
}, {
name: 'P2',
quantity: 1,
shop: 'S2',
image: '/images/p2.jpg',
price: 50,
_id: '62dbb03e90c4ca14ee3e06fb',
}, {
name: 'P3',
quantity: 1,
shop: 'S1',
image: '/images/p3.jpg',
price: 50,
_id: '62dbb03e90c4ca14ee3e06fc',
}];
const sellersSet = new Set(orderItems.map(x => x.shop));
const sellersArray = [...sellersSet];
// See here why the conversion to array is needed:
console.log({ sellersSet, sellersArray });

What is the best way to split data based on product owners in reactjs or nodejs

I need some idea!
Is there any possible way To separate user orders based on vendor email? I am trying to develop a multi-vendor project where vendors can be able to upload products. I am trying to do when a user orders from a different shop the orders need to be split based on vendor email.
Suppose a customer trying to buy from x vendor and y vendor products. When customers order the products the data look like the below array objects. It is difficult to show vendor orders in their dashboard who ordered your product. So I am trying to split the order based on email also the amount will be divided between the vendors from paymentDetail.amount when splitting the order.
[
{
_id: "622d70a49bd88b1599026318",
products: [
{
_id: "6223186e2278d4e502f5264a",
title: "Product number 1",
price: 600,
cartQuantity: 1,
vendor: {email: "vendor1#gmail.com"}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
},
],
paymentDetails: {
createdId: 1647145079,
date: "Sun Mar 13 2022",
amount: 700,
email: "user#gmail.com",
last4: "4242",
transaction: "p"
},
status: "Pending",
billing: {
country: "BD",
name: "Md. Fathe Karim",
phone: "+88010000000",
line1: "Madhabdi",
city: "Narshingdi",
postal_code: "1604",
state: "Bandarban"
}
}]
This is my POST request from frontend:
await fetch('https://guarded-ocean-73313.herokuapp.com/dashboard/orders', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({
products: [...cart], paymentDetails: {
createdId: paymentIntent.created,
date,
amount: paymentIntent.amount,
email: emailRef.current?.value,
billing: paymentIntent.billing_details,
last4: paymentMethod.card.last4,
transaction: paymentIntent?.client_secret.slice('_secret')[0]
},
status: 'Pending',
billing: {
country: countryRef.current?.value,
name: nameRef.current?.value,
phone: phoneRef.current?.value,
line1: addressRef.current?.value,
city: cityRef.current?.value,
postal_code: zipRef.current?.value,
state: stateRef.current?.value,
}
})
})
.then(res => res.json())
This is my order API
app.post('/dashboard/orders', async (req, res) => {
const productDetail = req.body
const result = await unityMartOrdersCollection.insertOne(productDetail)
res.json(result)
})
My expectation is something like this:
[
{
_id: "622d70a49bd88b1599026318", // Vendor 1 Order
products: [
{
_id: "6223186e2278d4e502f5264a",
title: "Product number 1",
price: 600,
cartQuantity: 1,
vendor: {email: "vendor1#gmail.com"}
}
],
paymentDetails: {
createdId: 1647145079,
date: "Sun Mar 13 2022",
amount: 600, // price redcuded because we divided the product
email: "user#gmail.com",
last4: "4242",
transaction: "p"
},
status: "Pending",
billing: {
country: "BD",
name: "Md. Fathe Karim",
phone: "+88010000000",
line1: "Madhabdi",
city: "Narshingdi",
postal_code: "1604",
state: "Bandarban"
}
},
{
_id: "622d70a49bd88b1599026319", // Vendor 2 Order
products: [
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
},
],
paymentDetails: {
createdId: 1647145079,
date: "Sun Mar 13 2022",
amount: 200, // price redcuded because we divided the product
email: "user#gmail.com",
last4: "4242",
transaction: "p"
},
status: "Pending",
billing: {
country: "BD",
name: "Md. Fathe Karim",
phone: "+88010000000",
line1: "Madhabdi",
city: "Narshingdi",
postal_code: "1604",
state: "Bandarban"
}
}
]
I think it's possible by the reduce method?
can someone give me any idea how can I be able to display the vendor's order into their dashboard? If my thinking is wrong you can share your idea.
This may be one possible solution to achieve the desired objective:
Code Snippet
const groupByVendor = arr => (
arr.map(order => (
Object.values( // sub-objective 1 - get values from object
order.products.reduce(
(fin, p) => ({
...fin,
...(
[p.vendor.email] in fin
? {
[p.vendor.email]: {
...fin[p.vendor.email],
products: fin[p.vendor.email].products.concat([{...p}]),
paymentDetails: {
...structuredClone(fin[p.vendor.email].paymentDetails),
amount: fin[p.vendor.email].paymentDetails.amount + p.price
} // sub-objective 2 - add price to existing amount
}
}
: {
[p.vendor.email]: {
...structuredClone(order), // sub-objective 3 - add order info here
paymentDetails: {
...structuredClone(order.paymentDetails),
amount: p.price // sub-objective 2 - set amount to price
},
products: [{...p}]
}
}
)
}),
{}
)
)
)).flat()
);
const rawData = [{
_id: "622d70a49bd88b1599026318",
products: [{
_id: "6223186e2278d4e502f5264a",
title: "Product number 1",
price: 600,
cartQuantity: 1,
vendor: {
email: "vendor1#gmail.com"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
vendor: {
email: "vendor2#gmail.com"
}
},
],
paymentDetails: {
createdId: 1647145079,
date: "Sun Mar 13 2022",
amount: 700,
email: "user#gmail.com",
last4: "4242",
transaction: "p"
},
status: "Pending",
billing: {
country: "BD",
name: "Md. Fathe Karim",
phone: "+88010000000",
line1: "Madhabdi",
city: "Narshingdi",
postal_code: "1604",
state: "Bandarban"
}
}];
console.log(groupByVendor(rawData));
Explanation
The idea is to break down the desired objective into simpler, more-manageable sub-objectives.
Sub-objective 1: A dictionary mapping vendors with orders
First, generate an object with props as the vendor email.
The values will be the actual order corresponding to the vendor
Once this object is created, all we need is the values array
Sub-objective 2: A mechanism to update the paymentDetailss amount
If processing a vendor that is not already present, set amount to price
If vendor already present, add price to existing amount
Sub-objective 3: Transform the structure of the object
The target requires each object in the array have paymentDetails, billing etc.
So, when generating the values for the vendor-object/dictionary/map, account for the corresponding transformations
The sub-objectives are marked in the code-snippet for reference.
Please use comments to ask any questions, clarifications, or suggest improvements.
NOTE
This answer employs structuredClone in order to perform deep-cloning of the order object.
My reference was Jeremy's this answer as well as this one
Modified Above Answer to Just Split Products without using structured clone , hope this might help
const groupByVendor = arr => (
arr.map(order => (
Object.values( // sub-objective 1 - get values from object
order.products.reduce(
(previousProduct, product) => ({
...previousProduct,
...(
[product.owner] in previousProduct
? {
[product.owner]: {
...previousProduct[product.owner],
products: previousProduct[product.owner].products.concat([{...product}]),
// sub-objective 2 - add price to existing amount
}
}
: {
[product.owner]: {
// sub-objective 3 - add order info here
products: [{...product}]
}
}
)
}),
{}
)
)
)).flat()
);
const rawData = [{
_id: "622d70a49bd88b1599026318",
products: [{
_id: "6223186e2278d4e502f5264a",
title: "Product number 1",
price: 600,
cartQuantity: 1,
owner: "vendor1#gmail.com"
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
owner: "vendor2#gmail.com"
},
{
_id: "622d4e9f9bd88b1599026317",
title: "asdas",
price: 100,
cartQuantity: 5,
owner: "vendor2#gmail.com"
},
]
}];
console.log(JSON.stringify(groupByVendor(rawData)));

How to loop over a an array that is already inside a map function without duplicating the contents

I have the following code with the following arrays. I want to loop through both of them and pull out some data, and put them inside a final array. I am able to do that, but the contents are duplicated. I tried reading about reduce but don't quite understand it, and am not sure if it's the right solution. I have also setup a jsfiddle
https://jsfiddle.net/anders_kitson/Lcqn6fgd/
var lineItems = [{
id: 'li_1HyhAZHk5l44uIELgsMWqHqB',
object: 'item',
amount_subtotal: 7500,
amount_total: 7500,
currency: 'cad',
description: 'The Spencer',
price: [Object],
quantity: 1
},
{
id: 'li_1HyhAZHk5l44uIELeNUsiZPu',
object: 'item',
amount_subtotal: 7500,
amount_total: 7500,
currency: 'cad',
description: 'The Gertie',
price: [Object],
quantity: 1
}
]
var arr = [{
id: 'prod_IS1wY1JvSv2CJg',
object: 'product',
active: true,
attributes: [],
created: 1606248785,
description: 'Shelf Set',
images: [
'https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq'
],
livemode: false,
metadata: {},
name: 'The Spencer',
statement_descriptor: null,
type: 'service',
unit_label: null,
updated: 1606248785
},
{
id: 'prod_IS299dMnC13Ezo',
object: 'product',
active: true,
attributes: [],
created: 1606249543,
description: 'Shelf Set',
images: [
'https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe'
],
livemode: false,
metadata: {},
name: 'The Gertie',
statement_descriptor: null,
type: 'service',
unit_label: null,
updated: 1606249543
}
];
let productArr = [];
arr.map((item) => {
lineItems.map((line) => {
productArr.push({
image: item.images[0],
name: item.name,
price: line.amount_total,
});
});
});
console.log(productArr);
This is the output I get where you can see the array repeats the values, and I know I have coded it this way I just don't know how to fix it.
[{
image: "https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq",
name: "The Spencer",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq",
name: "The Spencer",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
}]
To Be more clear this is the output that I want
[{
image: "https://files.stripe.com/links/fl_test_raNEqk9ZhzX3WdQsnvXX4gFq",
name: "The Spencer",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
},
]
I have tried the suggestion in the comments with the following
let b
arr.map((item) => {
b = lineItems.map((line) => {
return {
image: item.images[0],
name: item.name,
price: line.amount_total,
};
});
});
but it returns the same ones twice
[{
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
}, {
image: "https://files.stripe.com/links/fl_test_QPbrP76uNn4QadgcUwUnkmbe",
name: "The Gertie",
price: 7500
}]
Although not expressed directly in your question, it seems you're looking to do a join in javascript. The only things I see relating the two are 'name' in products and 'description' in the line items. So do a loop join on that.
Here's some sample code using your example but stripped down only to what's relevant:
var lineItems = [
{ amount_total: 7500, description: 'The Spencer' },
{ amount_total: 7500, description: 'The Gertie' }
]
var arr = [
{ images: ['Spencer Image 1'], name: 'The Spencer' },
{ images: ['Gertie Image 1'], name: 'The Gertie' }
]
let joined = arr
.flatMap(a => lineItems.map(li => ({a, li})))
.filter(obj => obj.a.name == obj.li.description)
.map(obj => ({
image: obj.a.images[0],
name: obj.a.name,
price: obj.li.amount_total
}));
console.log(joined);
Being a loop join, it may not be that efficient. To do a hash join is a little more involved. You can look through the source code of my developing project
fluent-data, or it might even be useful to you to use it directly if you can follow the documentation.
You can use a single map call and reference your second lineItems array either by index, if you know that the two arrays are the same length and order
const output = arr.map((o, i) => ({
name: o.name,
image: o.images[0],
price: lineItems[i].amount_total}
));
or by using find() to retrieve the relevant object.
const outputUsingFind = arr.map(o => {
const lineItem = lineItems.find(item => item.description === o.name);
// ** add lineItem valid check here **
return {
name: o.name,
image: o.images[0],
price: lineItem.amount_total};
});
var lineItems = [{amount_subtotal: 7500,amount_total: 700,description: 'The Spencer',},{amount_subtotal: 7500,amount_total: 500,description: 'The Gertie',}];
var arr = [{images: ['spencer image'],name: 'The Spencer',},{images: ['gertie image'],name: 'The Gertie'}];
// since your arrays are ordered the same you can access the second object using
// the index passed from map.
const output = arr.map((o, i) => ({
name: o.name,
image: o.images[0],
price: lineItems[i].amount_total}
));
console.log(output);
// if the two arrays are not in the same order you can use find() to retrieve
// the second object by property (you'll need to check
const outputUsingFind = arr.map(o => {
const lineItem = lineItems.find(item => item.description === o.name);
// ** add lineItem valid check here **
return {
name: o.name,
image: o.images[0],
price: lineItem.amount_total};
});
console.log(outputUsingFind);
.as-console-wrapper { max-height: 100% !important; top: 0; }

find an object in Array of Array

if i want for an example loop Through this Array to find specific item in Items Array how to approach that? i made this logic but it doesn't work
DATA.map((D)=>{
return D.items.find((item)=>{
return item.name ==='Blue Beanie'
})
})
this is the Array plus how to create new ONE array includes the both of items arrays to be like that: items: [{
id: 1,
name: 'Brown Brim',
price: 25
},
{
id: 2,
name: 'Blue Beanie',
price: 18
},
{
id: 3,
name: 'Adidas NMD',
price: 220
},
{
id: 4,
name: 'Adidas Yeezy',
price: 280
}
]
const DATA= [
{
id: 1,
title: 'Hats',
routeName: 'hats',
items: [
{
id: 1,
name: 'Brown Brim',
price: 25
},
{
id: 2,
name: 'Blue Beanie',
price: 18
}
]
},
{
id: 2,
title: 'Sneakers',
routeName: 'sneakers',
items: [
{
id: 3,
name: 'Adidas NMD',
price: 220
},
{
id: 4,
name: 'Adidas Yeezy',
price: 280
}
]
}
];
Transform DATA into list of items and find from that list your expected item
const res = DATA.flatMap((D) => D.items).find(
(item) => item.name === "Brown Brim"
)
const DATA = [
{
id: 1,
title: "Hats",
routeName: "hats",
items: [
{
id: 1,
name: "Brown Brim",
price: 25,
},
{
id: 2,
name: "Blue Beanie",
price: 18,
},
],
},
{
id: 2,
title: "Sneakers",
routeName: "sneakers",
items: [
{
id: 3,
name: "Adidas NMD",
price: 220,
},
{
id: 4,
name: "Adidas Yeezy",
price: 280,
},
],
},
]
const res = DATA.flatMap((D) => D.items).find(
(item) => item.name === "Brown Brim"
)
console.log(res)
Reference
Array.prototype.flatMap()
Maybe this is helpful?
const DATA= [
{id: 1,title:'Hats',routeName:'hats',
items:[{id: 1,name:"Brown Brim",price:25},
{id: 2,name: 'Blue Beanie',price: 18}]},
{id: 2,title: 'Sneakers',routeName: 'sneakers',
items: [{id: 3,name: 'Adidas NMD',price: 220},
{id: 4,name: 'Adidas Yeezy',price: 280}]}
];
console.log(DATA.map(D=>D.items.find(item=>item.name==='Brown Brim'))
.filter(e=>e))
The .map returns either an element matching your criterion or undefined, The chained .filter then removes all "falsy" elements, i. e. all the undefined ones.
As for the first question "loop Through this Array to find a specific item in Items Array"
given it is not sorted in any way, this can be done by iterating over the DATA array and search inside the items
If want to have access to the item from the outside of the 'forEach' scope you have to declare the variable outside
Regarding the second question, use the reduce function while iterating the array
NOTE: You can obviously combine both tasks as you already iterate through the array, so no need to do it twice. But to avoid confusion, I separated the logic.
Also, if you do choose to combine the tasks, using the reduce is not relevant, but very much like the answer to the first question, you can declare a buffer such as an array, and just copy items to it on the go (I'll leave out questions on performance for that matter)
const DATA = [
{
id: 1, title: 'Hats', routeName: 'hats',
items: [
{id: 1,name: 'Brown Brim',price: 25},
{id: 2,name: 'Blue Beanie',price: 18}
]
},
{
id: 2, title: 'Sneakers', routeName: 'sneakers',
items: [
{id: 3,name: 'Adidas NMD',price: 220},
{id: 4,name: 'Adidas Yeezy',price: 280}
]
}
];
//Question 1
//creating the object that will hold the item
//outside of the 'forEach' scope so we can use it later
let res = {};
const searchRes = DATA.forEach(entry => {
entry.items.forEach(item => {
if (item.name === 'Brown Brim')
//duplicating the item to a variable declared outside of this scope
res = { ...item
};
});
});
console.log(`Q1 - The item we found:`);
console.log(res);
// Question 2
// Merging all object inside the 'items' array using Reduce
const merged = DATA.reduce((acc, curr) =>
acc.concat(curr.items), []);
console.log(`Q2 - The merged array:`);
console.log(merged)

Filter an array of objects upon a value inside an array of objects inside in javascript

I am fetching an array of objects as following :
const data =
[ { id: 0, company: 'nike', items: [{ id: 0, name: 'caret', price: 100}] }
, { id: 1, company: 'adidas', items: [{ id: 1, name: 'mobile phone', price: 300}] }
]
I want to filter that array of objects by checking the value of the property "name" inside the items array if it is "Caret" or not. If yes, I want to return the same array of objects with all its content but filtered. Which means, it will filter out the object whose item's name is not caret. How can I achieve this in javascript?!
I suppose you are looking for that ?
const data =
[{ id: 0, company: 'nike', items: [{ id: 0, name: 'caret', price: 100}]}
,{ id: 1, company: 'adidas', items: [{ id: 1, name: 'mobile phone', price: 300}]}
]
const filterName = (arr, name)=>arr.filter(el=>el.items.some(x=>x.name==name))
onlyCaret = filterName(data,'caret')
console.log( onlyCaret[0].company ) // nike
console.log( onlyCaret ) // row 0 with { ... company: 'nike' ..}
.as-console-wrapper { max-height: 100% !important; top: 0; }
You need to use Array.filter and then loop through your items for a match
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
const data = [
{
id:0,
company: "nike"
items:[
name: "caret",
price:100
]
},
{
id:1,
company: "adidas"
items:[
name: "mobile phone",
price: 300
]
},
]
const filteredCompanies = data.filter((company)=>{
company.items.forEach((item)=>{
if(item.name === "nike") return true
})
})

Categories

Resources