get name of object in array when option.amount equals zero - javascript

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);

Related

concat strings from nested objects arrays

i need to concat all the 'externalId'(inside prod obj) + "id" (inside sup array) + "name" (inside product obj). What would be the best way to do that? I've tried with map and reduce but I wasn't successful. Any help will be appreciated.
const jsonResultKeys = ['AAA', 'BBB', 'CCC']
const items = [];
jsonResultKeys.forEach(k => {
const item = Jsonresult.items[k];
items.push({
description: item.product.name + ':' + item.product.sup[0] + ':'+ item.product.sup[0].prod.externalId ,
})
});
the output expected for this example:
[
{ description: '4444:2:product1'},
{ description: '3333:2:product2'},
{ description: '2222:1:product3'}
]
the json object:
const Jsonresult = {
items: {
'AAA': {
createdAt: '2021-02-11T17:25:22.960-03:00',
product: {
sup: [{
prod: {
externalId: **4444**
},
id: **2**
}],
name: "**product 1**"
},
total: 9.84,
quantity: 1,
price: 15,
updatedAt: '2021-02-11T17:25:22.960-03:00'
},
'BBB': {
createdAt: '2021-02-11T17:25:22.960-03:00',
product: {
sup: [{
prod: {
externalId: **3333**
},
id: **2**
}],
name: "**product 2**"
},
total: 9.84,
quantity: 1,
price: 15,
updatedAt: '2021-02-11T17:25:22.960-03:00'
},
'CCC': {
createdAt: '2021-02-11T17:25:22.960-03:00',
product: {
sup: [{
prod: {
externalId: **2222**
},
id: **1**
}],
name: "**product 3**"
},
}
},
}
The Array#map() method is the most logical method to use - see #MichaelMano's solution - but if you have to use .push() to populate items (const) then stick with .forEach() as follows:
Object.values( Jsonresult.items ).forEach(item => {
items.push( {description: `${item.product.sup[0].prod.externalId}:${item.product.sup[0].id}:${item.product.name}`} );
});
DEMO
const items = [];
const Jsonresult = {
items: {
'AAA': {
createdAt: '2021-02-11T17:25:22.960-03:00',
product: {
sup: [{
prod: {
externalId: 4444
},
id: 2
}],
name: "product 1"
},
total: 9.84,
quantity: 1,
price: 15,
updatedAt: '2021-02-11T17:25:22.960-03:00'
},
'BBB': {
createdAt: '2021-02-11T17:25:22.960-03:00',
product: {
sup: [{
prod: {
externalId: 3333
},
id: 2
}],
name: "product 2"
},
total: 9.84,
quantity: 1,
price: 15,
updatedAt: '2021-02-11T17:25:22.960-03:00'
},
'CCC': {
createdAt: '2021-02-11T17:25:22.960-03:00',
product: {
sup: [{
prod: {
externalId: 2222
},
id: 1
}],
name: "product 3"
},
}
},
};
Object.values( Jsonresult.items ).forEach(item => {
items.push( {description: `${item.product.sup[0].prod.externalId}:${item.product.sup[0].id}:${item.product.name}`} );
});
console.log( items );
You could do the following, Map over the results and return an object, this will create an array of objects.
You wont even need the keys.
const map = Object.values(Jsonresult.items).map((item) => {
return {
description: `${item.product.sup[0].prod.externalId}:${item.product.sup[0].id}:${item.product.name}`,
};
});
[
{ description: '4444:2:product 1' },
{ description: '3333:2:product 2' },
{ description: '2222:1:product 3' }
]

Creating an array by nested map with filtering

const market = [
{
id: 0,
properties: [{ name: 'salad', price: 99, isMain: true }],
value: "1"
},
{
id: 1,
properties: [{ name: 'patato', price: 100, isMain: false }],
value: "2"
},
{
id: 2,
properties: [{ name: 'strawberry', price: 101, isMain: true }],
value: "3"
},
];
I have data like above, I want to make list of properties which has isMain property is true like the example below. How can I best do this with ES6?
expectation ==>
[
{
name: 'salad',
price: 99,
isMain: true,
},
{
name: 'strawberry',
price: 101,
isMain: true,
},
];
You need to flat the array and then use the filter method to get your desired items from nested array, this will work even if you have multiple items in properties array.
var filtredItems = [];
const market = [
{
id: 0,
properties: [{ name: 'salad', price: 99, isMain: true }],
value: "1"
},
{
id: 1,
properties: [{ name: 'patato', price: 100, isMain: false }, { name: 'second', price: 100, isMain: true }],
value: "2"
},
{
id: 2,
properties: [{ name: 'strawberry', price: 101, isMain: true }],
value: "3"
},
];
filtredItems = market.flatMap(x => x.properties).filter(prop=> prop.isMain);
console.log('filtredItems', filtredItems)
Use ES6 map then filter
const market = [
{
id: 0,
properties: [{ name: 'salad', price: 99, isMain: true }],
value: "1"
},
{
id: 1,
properties: [{ name: 'patato', price: 100, isMain: false }],
value: "2"
},
{
id: 2,
properties: [{ name: 'strawberry', price: 101, isMain: true }],
value: "3"
},
];
const results = market.map(product => product.properties[0]).filter(p => !!p.isMain);
console.log(results);
NB: it is quite weird to have a single hash in an array.
you can bind filter with map to get somthing like this
i don't know if you have multiple values in properties field:
market.filter(m => m.properties?.[0].isMain)
.map( m => ({ name: m.name, price: m.properties?.[0].isMain, isMain: m.properties?.[0].isMain }))

How to duplicate an object in an array by given quantity, ES6 and above

I'm trying to convert an array of objects where i return duplicated objects if the object properties quantity is greater than 1.
const objects = [
{ id: 1, name: "Scissor", price: 2, quantity: 3 },
{ id: 2, name: "Hat", price: 6.5, quantity: 1 },
{ id: 3, name: "Socks", price: 0.5, quantity: 5 },
];
// desired return
[
{ id: 1, name: "Scissor", price: 2 }
{ id: 1, name: "Scissor", price: 2 }
{ id: 1, name: "Scissor", price: 2 }
{ id: 2, name: "Hat", price: 6.5}
{ id: 3, name: "Socks", price: 0.5 }
{ id: 3, name: "Socks", price: 0.5 }
{ id: 3, name: "Socks", price: 0.5 }
{ id: 3, name: "Socks", price: 0.5 }
{ id: 3, name: "Socks", price: 0.5 }
]
My code:
const objects = [
{ id: 1, name: "Scissor", price: 2, quantity: 3 },
{ id: 2, name: "Hat", price: 6.5, quantity: 1 },
{ id: 3, name: "Socks", price: 0.5, quantity: 5 },
];
let newObjects= [];
Object.entries(objects).forEach(([key, value]) => {
for (let i=0; i < value.quantity; i++){
newObjects.push({ id: value.id, name: value.name, price: value.price})
}
});
console.log(newObjects);
So my code above does work, does return what i wanted, however i feel like there is a better/smoother and more of ES6 and beyond method. Could anyone please suggest a better way?
You could use .fill() and .flatMap().
const objects = [
{ id: 1, name: "Scissor", price: 2, quantity: 3 },
{ id: 2, name: "Hat", price: 6.5, quantity: 1 },
{ id: 3, name: "Socks", price: 0.5, quantity: 5 },
];
let newObjects = objects.flatMap(e=>
Array(e.quantity).fill({id: e.id, name: e.name, price: e.price})
);
console.log(newObjects);
You can use an array reduce along with an array fill.
The map is required only if you want to have unique references otherwise you can fill using the same object.
const objects = [
{ id: 1, name: "Scissor", price: 2, quantity: 3 },
{ id: 2, name: "Hat", price: 6.5, quantity: 1 },
{ id: 3, name: "Socks", price: 0.5, quantity: 5 },
];
const output = objects.reduce((a, c) => {
return a.concat(Array(c.quantity).fill({}).map(x=>({
id: c.id,
name: c.name,
price: c.price
})))
}, []);
console.log(output)

Comparing two arrays and adding objects to the other one

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; }

Merge Duplicate object in array

I have an array I need to merge duplicate values with the sum of amount.
What would be an efficient algorithm
var arr = [{
item: {
id: 1,
name: "Abc"
},
amount: 1
}, {
item: {
id: 1,
name: "Abc"
},
amount: 2
}, {
item: {
id: 2,
name: "Abc"
},
amount: 2
},{
item: {
id: 1,
name: "Abc"
},
amount: 2
}]
I need solution as
[{
item: {
id: 1,
name: "Abc"
},
amount: 5
}, {
item: {
id: 2,
name: "Abc"
},
] amount: 2
}]
simply use Object.values() with Array.reudce() to merge objects and then get the values:
var arr = [{ item: { id: 1, name: "Abc" }, amount: 1 }, { item: { id: 1, name: "Abc" }, amount: 2 }, { item: { id: 2, name: "Abc" }, amount: 2 },{ item: { id: 1, name: "Abc" }, amount: 2 }];
var result = Object.values(arr.reduce((a,curr)=>{
if(!a[curr.item.id])
a[curr.item.id] = Object.assign({},curr); // Object.assign() is used so that the original element(object) is not mutated.
else
a[curr.item.id].amount += curr.amount;
return a;
},{}));
console.log(result);
used map to catch em all :D
var arr = [{ item: { id: 1, name: "Abc" }, amount: 1 }, { item: { id: 1, name: "Abc" }, amount: 2 }, { item: { id: 2, name: "Abc" }, amount: 2 },{ item: { id: 1, name: "Abc" }, amount: 2 }];
var res = {};
arr.map((e) => {
if(!res[e.item.id]) res[e.item.id] = Object.assign({},e); // clone, credits to: #amrender singh
else res[e.item.id].amount += e.amount;
});
console.log(Object.values(res));

Categories

Resources