Related
Suppose I have an array of object as,
const attachmentData = [{name: 'Suman Baidh',attachment: ["123","456"]},
{name: 'John Sigma',attachment: ["789","101112]},
{name: 'Binay', attachment: ["131415","161718","192021]}]
And another array of object as,
const attachmentDetail = [{"id":"123",details:{"cost":10,"quantity":20}},
{"id":"456",details: {"cost":15,"quantity":28}},
{"id":"789",details:{"cost":4,"quantity":9}},
{"id":"101112",details:{"cost":40,"quantity":2}},
{"id":"131415",details:{"cost":12,"quantity":9}},
{"id":"161718",details:{"cost":45,"quantity":2}},
{"id":"192021",details:{"cost":120,"quantity":1}}]
I want the O/P as: Such that the id which is matched with attachmentDetail also has name along with it and pushed to new array.
[{"name":"Suman Baidh","id":"123","cost":10,"quantity":20},
{"name":"Suman Baidh","id":"456","cost":15,"quantity":28},
{"name":"John Sigma","id":"789","cost":4,"quantity":9} ,
{"name":"John Sigma","id":"101112","cost":40,"quantity":2},
{"name":"Binay","id":"131415","cost":12,"quantity":9},
{"name":"Binay","id":"161718","cost":45,"quantity":2},
{"name":"Binay","id":"192021","cost":120,"quantity":1}]
For this I tried as,
let newArray = []
for(let i = 0;i<attachmentData.length;i++)}{
for(let j = 0;j<attachmentData[i].attachment.length;j++){
if(attachmentData[i].attachment[j] == attachmentDetail.id){
newArray.push(...attachmentData[i], ... attachmentData[i].attachment[j]
}
}
}
On console.log(newArray) , its giving me not the answer I wanted.
If anyone needs any further information, please let me know. Any suggestion would be really helpful.
Try this,
const attachmentData = [
{ name: "Suman Baidh", attachment: ["123", "456"] },
{ name: "John Sigma", attachment: ["789", "101112"] },
{ name: "Binay", attachment: ["131415", "161718", "192021"] },
];
const attachmentDetail = [
{ id: "123", details: { cost: 10, quantity: 20 } },
{ id: "456", details: { cost: 15, quantity: 28 } },
{ id: "789", details: { cost: 4, quantity: 9 } },
{ id: "101112", details: { cost: 40, quantity: 2 } },
{ id: "131415", details: { cost: 12, quantity: 9 } },
{ id: "161718", details: { cost: 45, quantity: 2 } },
{ id: "192021", details: { cost: 120, quantity: 1 } },
];
let newArr = [];
attachmentData.forEach(({name, attachment}) => {
attachment.forEach((id) => {
const { details: { cost, quantity } } = attachmentDetail.find((item) => item.id === id)
newArr.push({ name, id, cost, quantity})
})
})
console.log(newArr)
NOTE: Try to use find, map, forEach, filter functions to simplify the for loop whenever possible.
The problem is in the line:
if (attachmentData[i].attachment[j] === attachmentDetail.id) {
Here attachmentDetail is an array. To access its element you need to use attachmentDetail[index].id.
You will need to loop through it to match the id from attachmentData.
const attachmentData = [{name: 'Suman Baidh', attachment: ["123", "456"]},
{name: 'John Sigma', attachment: ["789", "101112"]},
{name: 'Binay', attachment: ["131415", "161718", "192021"]}];
const attachmentDetail = [{"id": "123", details: {"cost": 10, "quantity": 20}},
{"id": "456", details: {"cost": 15, "quantity": 28}},
{"id": "789", details: {"cost": 4, "quantity": 9}},
{"id": "101112", details: {"cost": 40, "quantity": 2}},
{"id": "131415", details: {"cost": 12, "quantity": 9}},
{"id": "161718", details: {"cost": 45, "quantity": 2}},
{"id": "192021", details: {"cost": 120, "quantity": 1}}];
let newArray = []
for (let i = 0; i < attachmentData.length; i++) {
for (let j = 0; j < attachmentData[i].attachment.length; j++) {
for (let k = 0; k < attachmentDetail.length; ++k) {
if (attachmentData[i].attachment[j] === attachmentDetail[k].id) {
newArray.push({
name: attachmentData[i].name,
id: attachmentDetail[k].id,
...attachmentDetail[k].details
});
}
}
}
}
console.log(newArray);
Or
const attachmentData = [{name: 'Suman Baidh', attachment: ["123", "456"]},
{name: 'John Sigma', attachment: ["789", "101112"]},
{name: 'Binay', attachment: ["131415", "161718", "192021"]}];
const attachmentDetail = [{"id": "123", details: {"cost": 10, "quantity": 20}},
{"id": "456", details: {"cost": 15, "quantity": 28}},
{"id": "789", details: {"cost": 4, "quantity": 9}},
{"id": "101112", details: {"cost": 40, "quantity": 2}},
{"id": "131415", details: {"cost": 12, "quantity": 9}},
{"id": "161718", details: {"cost": 45, "quantity": 2}},
{"id": "192021", details: {"cost": 120, "quantity": 1}}];
const newArray = attachmentDetail.map(x => ({
name: attachmentData.filter(y => y.attachment.includes(x.id))[0].name,
id: x.id, ...x.details
}));
console.log(newArray);
Output
[
{ name: 'Suman Baidh', id: '123', cost: 10, quantity: 20 },
{ name: 'Suman Baidh', id: '456', cost: 15, quantity: 28 },
{ name: 'John Sigma', id: '789', cost: 4, quantity: 9 },
{ name: 'John Sigma', id: '101112', cost: 40, quantity: 2 },
{ name: 'Binay', id: '131415', cost: 12, quantity: 9 },
{ name: 'Binay', id: '161718', cost: 45, quantity: 2 },
{ name: 'Binay', id: '192021', cost: 120, quantity: 1 }
]
I think that something like this will work!
const attachmentData = [
{ name: "Suman Baidh", attachment: ["123", "456"] },
{ name: "John Sigma", attachment: ["789", "101112"] },
{ name: "Binay", attachment: ["131415", "161718", "192021"] },
];
const attachmentDetail = [
{ id: "123", details: { cost: 10, quantity: 20 } },
{ id: "456", details: { cost: 15, quantity: 28 } },
{ id: "789", details: { cost: 4, quantity: 9 } },
{ id: "101112", details: { cost: 40, quantity: 2 } },
{ id: "131415", details: { cost: 12, quantity: 9 } },
{ id: "161718", details: { cost: 45, quantity: 2 } },
{ id: "192021", details: { cost: 120, quantity: 1 } },
];
const newArray = attachmentDetail.map((detail) => {
const data = attachmentData.find((data) => data.attachment.includes(detail.id));
return {name: data.name, id: detail.id, ...detail.details}
})
If we want to deal with two arrays(specially for large sets of data), It's always good to convert one array to object(hash) and iterate over the other to find the matching.
const attachmentData = [{name: 'Suman Baidh',attachment: ["123","456"]}, {name: 'John Sigma',attachment: ["789","101112"]}, {name: 'Binay', attachment: ["131415","161718","192021"]}]
const attachmentDetail = [{"id":"123",details:{"cost":10,"quantity":20}}, {"id":"456",details: {"cost":15,"quantity":28}}, {"id":"789",details:{"cost":4,"quantity":9}}, {"id":"101112",details:{"cost":40,"quantity":2}}, {"id":"131415",details:{"cost":12,"quantity":9}}, {"id":"161718",details:{"cost":45,"quantity":2}}, {"id":"192021",details:{"cost":120,"quantity":1}}];
function customMerge(data, attachments) {
const hashById = attachments.reduce((acc, ele) => {
acc[ele.id] = ele;
return acc;
}, {});
return data.reduce((acc, {attachment, name}) => {
return acc.concat(attachment.map(id => ({name, id, details: hashById[id].details})));
},[]);
}
console.log(customMerge(attachmentData, attachmentDetail))
const attachmentData = [
{ name: 'Suman Baidh', attachment: [ '123', '456' ] },
{ name: 'John Sigma', attachment: [ '789', '101112' ] },
{ name: 'Binay', attachment: [ '131415', '161718', '192021' ] },
];
const attachmentDetail = [
{ id: '123', details: { cost: 10, quantity: 20 } },
{ id: '456', details: { cost: 15, quantity: 28 } },
{ id: '789', details: { cost: 4, quantity: 9 } },
{ id: '101112', details: { cost: 40, quantity: 2 } },
{ id: '131415', details: { cost: 12, quantity: 9 } },
{ id: '161718', details: { cost: 45, quantity: 2 } },
{ id: '192021', details: { cost: 120, quantity: 1 } },
];
const newArray = [];
for (let i = 0; i < attachmentData.length; i++) {
const { attachment } = attachmentData[i];
for (let j = 0; j < attachment.length; j++) {
attachmentDetail.some(element => {
if (element.id === attachment[j]) {
newArray.push({ name: attachmentData[i].name, ...element });
return true;
}
});
}
}
console.log(newArray);
You can first create a Map whose keys are the attachment ids and value is the name corresponding to that attachment.
Then loop over attachmentDetail array and just add the name using the Map created.
const
attachmentData = [{ name: "Suman Baidh", attachment: ["123", "456"] }, { name: "John Sigma", attachment: ["789", "101112"] }, { name: "Binay", attachment: ["131415", "161718", "192021"] }],
attachmentDetail = [{ id: "123", details: { cost: 10, quantity: 20 } }, { id: "456", details: { cost: 15, quantity: 28 } }, { id: "789", details: { cost: 4, quantity: 9 } }, { id: "101112", details: { cost: 40, quantity: 2 } }, { id: "131415", details: { cost: 12, quantity: 9 } }, { id: "161718", details: { cost: 45, quantity: 2 } }, { id: "192021", details: { cost: 120, quantity: 1 } }],
map = attachmentData.reduce((m, o) => (o.attachment.map((a) => m.set(a, o.name)), m), new Map()),
res = attachmentDetail.map(({ id, details }) => (name => ({ id, name, ...details }))(map.get(id)));
console.log(res);
I am trying pushing the name but in the console log I see just a number and not the actual name
What am i doing wrong??
const cartItems = [{
id: 1,
name: "Soup",
price: 3,
category: "starters",
count: 1
},
{
id: 2,
name: "Pâté",
price: 5,
category: "starters",
count: 1
},
{
id: 9,
name: "Sticky toffee",
price: 18,
category: "desserts",
count: 1
}
]
var dishesArray = [];
var groupByCategory = []
cartItems.reduce(function(res, value) {
if (!res[value.category]) {
res[value.category] = {
category: value.category,
count: 0,
dishes: dishesArray.push(value.name), // problem here
};
groupByCategory.push(res[value.category]);
}
res[value.category].count += value.count;
return res;
}, {});
console.log(groupByCategory)
Expected output
[{category: "starters", count: 2, dishes:["Soup","Pâté"]},
{category: "desserts", count: 1, dishes:["Sticky toffee"]}]
As mentioned, a push returns an int
I believe you are looking for this much shortened reduce
const cartItems = [
{ id: 1, name: "Soup", price: 3, category: "starters", count: 1 },
{ id: 2, name: "Pâté", price: 5, category: "starters", count: 1 },
{ id: 9, name: "Sticky toffee", price: 18, category: "desserts", count: 1}
];
const groupByCategory = cartItems.reduce(function(res, value) {
const cat = value.category;
res[cat] = res[cat] || { category: cat, count: 0, dishes: [] };
res[cat].count += value.count;
res[cat].dishes.push(value.name)
return res;
}, {});
console.log(groupByCategory)
I'm trying to get an array of names of objects that have options.amount all equals to zero. Thanks for your time. This is what i tryed:
let variants = [
{
name: 'extra',
options: [
{
name: 'meat',
price: 3,
amount: 0
},
{
name: 'cheese',
price: 1,
amount: 0
}
]
},
{
name: 'sauce',
options: [
{
name: 'ketchup',
price: 2,
amount: 1
},
{
name: 'mayo',
price: 1,
amount: 0
}
]
}
];
//Expected output = ['extra']
let arrayOfOptionsNames = variants.map(x => x.options.filter(y => y.amount === 0 ? x.name : 0))
console.log(arrayOfOptionsNames)
You could use Array.prototype.filter() and Array.prototype.every() method to get your result. Every method test if every elements of the array pass the test by the given callback function and returns a boolean value.
const variants = [
{
name: 'extra',
options: [
{
name: 'meat',
price: 3,
amount: 0,
},
{
name: 'cheese',
price: 1,
amount: 0,
},
],
},
{
name: 'sauce',
options: [
{
name: 'ketchup',
price: 2,
amount: 1,
},
{
name: 'mayo',
price: 1,
amount: 0,
},
],
},
];
const ret = variants
.filter((x) => x.options.every((y) => y.amount === 0))
.map((x) => x.name);
console.log(ret);
You could filter and get the wanted property.
let variants = [{ name: 'extra', options: [{ name: 'meat', price: 3, amount: 0 }, { name: 'cheese', price: 1, amount: 0 }] }, { name: 'sauce', options: [{ name: 'ketchup', price: 2, amount: 1 }, { name: 'mayo', price: 1, amount: 0 }] }],
result = variants
.filter(({ options }) => options.every(({ amount }) => !amount))
.map(({ name }) => name);
console.log(result);
I have two arrays:
let array1 = [
{
_id: '5eaf8eeac436dbc9b7d75f35',
name: 'Strawberry',
category: 'organic',
image: '/productImages/australian.jpg',
price: '9.65',
quantity: 1
},
{
_id: '5eaf8f61c436dbc9b7d75f36',
name: 'Organic Wild Blue Berry',
category: 'organic',
image: '/productImages/owbb.jpg',
price: '12.50',
quantity: 1
},
{
_id: '5eb0ac47d98c817d9a82df82',
name: 'Mango',
category: 'australian',
image: '/productImages/australian.jpg',
price: '12.25',
quantity: 1
},
{
_id: '5eb0ac71d98c817d9a82df83',
name: 'Peas',
category: 'conventional',
image: '/productImages/owbb.jpg',
price: '25.12',
quantity: 1
}
]
let array2 = [
{
_id: '5ec00539f7ff70566fd8a557',
productid: {
_id: '5eaf8eeac436dbc9b7d75f35',
name: 'Strawberry',
category: 'organic',
image: '/productImages/australian.jpg',
price: '9.65'
},
quantity: 3
},
{
_id: '5ec00539f7ff70566fd8a558',
productid: {
_id: '5eaf8f61c436dbc9b7d75f36',
name: 'Organic Wild Blue Berry',
category: 'organic',
image: '/productImages/owbb.jpg',
price: '12.50'
},
quantity: 3
}
]
I need to check if productId of array2 matches any object _id of array1. If so, I need to add each object's quantities to one another. Otherwise, I need to push one to another.
For example, if "_id": "5eb0ac71d98c817d9a82df83" doesn't exist in any object of array2's productId, push it into array2. And if any element of array2 doesn't exist in array1, push it into array1.
I managed to update the quantity if one of the objects included in the other array but can't figure out a way to push the rest of the objects to one another.
Here is how I combined the quantities of matching _id from array1 to productId in array2
if (array1.length > 0) {
for (let i = 0; i < array2.length; i++) {
for (let k = 0; k < array1.length; k++) {
if (array2[i].productid._id === array1[k]._id) {
array1[k].quantity = array1[k].quantity + array2[i].quantity
array2[i].quantity = array1[k].quantity
}
}
}
}
Expected result based on example above:
array1 = [
{
_id: '5eaf8eeac436dbc9b7d75f35',
name: 'Strawberry',
category: 'organic',
image: '/productImages/australian.jpg',
price: '9.65',
quantity: 4
},
{
_id: '5eaf8f61c436dbc9b7d75f36',
name: 'Organic Wild Blue Berry',
category: 'organic',
image: '/productImages/owbb.jpg',
price: '12.50',
quantity: 4
},
{
_id: '5eb0ac47d98c817d9a82df82',
name: 'Mango',
category: 'australian',
image: '/productImages/australian.jpg',
price: '12.25',
quantity: 1
},
{
_id: '5eb0ac71d98c817d9a82df83',
name: 'Peas',
category: 'conventional',
image: '/productImages/owbb.jpg',
price: '25.12',
quantity: 1
}
]
array2 = [
{
_id: '5ec00539f7ff70566fd8a557',
productid: {
_id: '5eaf8eeac436dbc9b7d75f35',
name: 'Strawberry',
category: 'organic',
image: '/productImages/australian.jpg',
price: '9.65'
},
quantity: 4
},
{
_id: '5ec00539f7ff70566fd8a558',
productid: {
_id: '5eaf8f61c436dbc9b7d75f36',
name: 'Organic Wild Blue Berry',
category: 'organic',
image: '/productImages/owbb.jpg',
price: '12.50'
},
quantity: 4
},
{
_id: 'auto-generated-id',
productid: {
_id: '5eb0ac47d98c817d9a82df82',
name: 'Mango',
category: 'australian',
image: '/productImages/australian.jpg',
price: '12.25'
},
quantity: 1
},
{
_id: 'auto-generated-id',
productid: {
_id: '5eb0ac71d98c817d9a82df83',
name: 'Peas',
category: 'conventional',
image: '/productImages/owbb.jpg',
price: '25.12'
},
quantity: 1
}
]
You can do this with reduce function. Here is my try:
var array1 =[{"_id":"5eaf8eeac436dbc9b7d75f35","name":"Strawberry","category":"organic","image":"/productImages/australian.jpg","price":"9.65","quantity":1},{"_id":"5eaf8f61c436dbc9b7d75f36","name":"Organic Wild Blue Berry","category":"organic","image":"/productImages/owbb.jpg","price":"12.50","quantity":1},{"_id":"5eb0ac47d98c817d9a82df82","name":"Mango","category":"australian","image":"/productImages/australian.jpg","price":"12.25","quantity":1},{"_id":"5eb0ac71d98c817d9a82df83","name":"Peas","category":"conventional","image":"/productImages/owbb.jpg","price":"25.12","quantity":1}];
var array2=[ { _id: '5ec00539f7ff70566fd8a557', productid: { _id: '5eaf8eeac436dbc9b7d75f35', name: 'Strawberry', category: 'organic', image: '/productImages/australian.jpg', price: '9.65', }, quantity: 3 }, { _id: '5ec00539f7ff70566fd8a558', productid: { _id: '5eaf8f61c436dbc9b7d75f36', name: 'Organic Wild Blue Berry', category: 'organic', image: '/productImages/owbb.jpg', price: '12.50', }, quantity: 3 }];
result = array1.reduce((acc, elem, i)=>{
index = array2.findIndex(val=>val.productid._id == elem._id);
if(index!=-1) {
array2[index].quantity = elem.quantity += array2[index].quantity;
} else {
array2.push({_id:'some_id'+i, productid: elem, quantity: elem.quantity})
}
acc.push(elem);
return acc;
},[]);
result = [...result, ...array2.filter(elem=> !array1.some(val=>val._id == elem.productid._id)).map(({productid, quantity})=>({...productid, quantity}))];
console.log(result);
console.log(array2)
I would add the quantities of the first array to the second, then regenerate the second array based on the first:
// Create a lookup table to make the whole thing O(n)
const entryById = {};
for(const item of array2)
entryById[item.productid._id] = item;
// Update array2 with the amount of array1
for(const item of array1) {
if(entryById[item]) {
entryById[item].amount += item.amount;
} else {
array2.push(entryById[item] = {
_id: 'generated',
productid: item,
amount: item.amount,
});
}
}
// Regenerate array1
array1 = array2.map(({ productid, amount }) => ({ ...productid, amount }));
I find it strange though that you maintain two different datastructures here.
You could take a hash table for the second array and iterate the first and push a new data set and update the values.
let array1 = [{ _id: "5eaf8eeac436dbc9b7d75f35", name: "Strawberry", category: "organic", image: "/productImages/australian.jpg", price: "9.65", quantity: 1 }, { _id: "5eaf8f61c436dbc9b7d75f36", name: "Organic Wild Blue Berry", category: "organic", image: "/productImages/owbb.jpg", price: "12.50", quantity: 1 }, { _id: "5eb0ac47d98c817d9a82df82", name: "Mango", category: "australian", image: "/productImages/australian.jpg", price: "12.25", quantity: 1 }, { _id: "5eb0ac71d98c817d9a82df83", name: "Peas", category: "conventional", image: "/productImages/owbb.jpg", price: "25.12", quantity: 1 }],
array2 = [{ _id: '5ec00539f7ff70566fd8a557', productid: { _id: '5eaf8eeac436dbc9b7d75f35', name: 'Strawberry', category: 'organic', image: '/productImages/australian.jpg', price: '9.65', }, quantity: 3 }, { _id: '5ec00539f7ff70566fd8a558', productid: { _id: '5eaf8f61c436dbc9b7d75f36', name: 'Organic Wild Blue Berry', category: 'organic', image: '/productImages/owbb.jpg', price: '12.50', }, quantity: 3 }],
ids = array2.reduce((r, o) => {
r[o.productid._id] = o; return r;
}, {}),
result = array1.forEach(o => {
if (ids[o._id]) {
const value = o.quantity;
o.quantity += ids[o._id].quantity;
ids[o._id].quantity += value;
} else {
const { quantity, ...productid } = o;
array2.push(ids[productid._id] = { _id: 'auto-generated-id', productid, quantity });
}
});
console.log(array1);
console.log(array2);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have single array, I want to separate category and category Product
const product = [{
id: 1,
name: 'Cloth',
cat: ['fashion', 'man', 'women']
}, {
id: 2,
name: 'Shoes',
cat: ['fashion']
}, {
id: 3,
name: "hat",
cat: ['man', 'fashion']
}]
How to Separate category value from Product array.
const cat = ['fashion','man','women']
How to Separate category and Product
const result = [{
cat: 'fashion',
[{
id: 1,
name: 'Cloth'
}, {
id: 2,
name: 'Shoes'
}, {
id: 3,
name: "hat"
}]
}, {
cat: 'man',
[{
id: 1,
name: 'Cloth'
}, {
d: 3,
name: "hat"
}]
}, {
cat: 'women',
[{
id: 1,
name: 'Cloth'
}]
}]
How to develop this type of array please help me. Any one know please help me, Advance tanks for reply
First answer:
let categories = [];
const product = [
{ id: 1, name: "Cloth", cat: ["fashion", "man", "women"] },
{ id: 2, name: "Shoes", cat: ["fashion"] },
{ id: 3, name: "hat", cat: ["man", "fashion"] }
];
product.forEach((p) => {
p.cat.forEach((cat) => {
if(!categories.includes(cat)) {
categories.push(cat)
}
})
})
console.log(categories) // ['fashion','man','women']
If you one to get All categories from product Array.
let allCategories = [];
product.forEach(p => {
allCategories.push(...p.cat);
});
allCategories = [...new Set(allCategories)];
For second question I will use the result of first question:
allCategories.forEach(categorie => {
result.push(
{
cat: categorie,
products : product.filter(p => {
if(p.cat.includes(categorie)) {
return {
id : p.id,
name : p.name
}
}
})
}
)
})