I have this array object:
0:
id: "123123"
cost: 100
quantity: 2
1:
id: "112233"
cost: 100
quantity: 5
2:
id: "112233"
cost: 100
quantity: 0
3:
id: "126233"
cost: 100
quantity: 0
What I want is to scan the whole object array and delete the ones with 0 quantity value. How do I do this with javascript?
Using the function from my answer at remove objects from array by object property,
filterInPlace(array, item => item.quantity !== 0);
const filterInPlace = (array, predicate) => {
let end = 0;
for (let i = 0; i < array.length; i++) {
const obj = array[i];
if (predicate(obj)) {
array[end++] = obj;
}
}
array.length = end;
};
const arr = [
{
id: "123123",
cost: 100,
quantity: 2,
},
{
id: "112233",
cost: 100,
quantity: 5,
},
{
id: "112233",
cost: 100,
quantity: 0,
},
{
id: "126233",
cost: 100,
quantity: 0,
},
];
filterInPlace(arr, item => item.quantity !== 0);
console.log(arr);
This does modify the array in place. If you don’t need that, the Array#filter equivalent is probably better.
This is linear-time, constant space, whereas solutions based splice have a worse worst case(s). (#Hogan’s answer is also linear-time; this is the same idea as it, but with the loops merged.)
array.filter() creates new array with the filtered objects.
take a look at this:
const values = [
{id: '123123', cost: 100, quantity: 2},
{id: '112233', cost: 100, quantity: 5},
{id: '112233', cost: 100, quantity: 0},
{id: '126233', cost: 100, quantity: 0},
]
const filtered = values.filter((obj) => obj.quantity !== 0)
console.log(filtered)
// expected output: [ { id: '123123', cost: 100, quantity: 2 }, { id: '112233', cost: 100, quantity: 5 } ]
let data = [
{id: "123123",
cost: 100,
quantity: 2},
{ id: "112233",
cost: 100,
quantity: 5},
{ id: "112233",
cost: 100,
quantity: 0},
{id: "126233",
cost: 100,
quantity: 0}
];
let i =0;
while (i < data.length) {
if (data[i].quantity === 0) {
data.splice(i, 1);
} else {
++i;
}
}
console.table(data);
Just iterate over the elements of the array and check for the value of quantity and delete with splice:
let arr = [
{
id: "123123",
cost: 100,
quantity: 2,
},
{
id: "112233",
cost: 100,
quantity: 5,
},
{
id: "112233",
cost: 100,
quantity: 0
},
{
id: "126233",
cost: 100,
quantity: 0
}
];
let len = arr.length;
for( let i = 0; i < len; i++) {
if(arr[i]['quantity'] === 0){
arr.splice(i--,1);
len--;
}
}
console.log(arr);
output:
[
{ id: '123123', cost: 100, quantity: 2 },
{ id: '112233', cost: 100, quantity: 5 }
]
I usually don't recommend mutating the input itself. But since you have this requirement, Just created this utility in order to fulfil your requirement.
let data = [
{ id: '123123', cost: 100, quantity: 2 },
{ id: '112233', cost: 100, quantity: 5 },
{ id: '112232', cost: 100, quantity: 0 },
{ id: '112234', cost: 200, quantity: 0 },
{ id: '112235', cost: 400, quantity: 1 }
]
const indexesToBeRemoved = [];
data.forEach((d, index) => {
if(d.quantity === 0) indexesToBeRemoved.push(index)
})
const length = indexesToBeRemoved.length;
for(let i=length-1; i>=0; i--) {
data.splice(indexesToBeRemoved[i],1)
}
console.log(data)
One another way of fulfilling your requirement.
let data = [
{ id: '123123', cost: 100, quantity: 2 },
{ id: '112233', cost: 100, quantity: 5 },
{ id: '112232', cost: 100, quantity: 0 },
{ id: '112234', cost: 100, quantity: 0 },
{ id: '112235', cost: 100, quantity: 1 }
]
let numberOfItemsToBeRemoved = 0;
data.forEach((d, index) => {
if(d.quantity === 0) {
data.unshift(...data.splice(index, 1))
numberOfItemsToBeRemoved++;
}
})
console.log("deleted items: ", data.splice(0, numberOfItemsToBeRemoved))
console.log(data)
Hope this helps.
If you really have an array you can't delete -- most libraries that do this functionally will create a new object. If you want to "delete" items what you really have to do is move other elements down to over write the ones you no longer want.
So I would use the following steps.
Check to see if the filter item appears at all -- if it does not there is nothing to do.
If it does appear then then let n be the index of the first item to filter. next is the next item out after it.
loop (index from n to index+next < size of array)
while next is an item to filter increase next by 1
copy from next to index
--> increase next by 1 and back to start of loop
first get element indexes and then delete them
arr=[{
'id': "123123",
cost: 100,
quantity: 2
},
{
id: "112233",
cost: 100,
quantity: 5
},
{
id: "112233",
cost: 100,
quantity: 0
},
{
id: "126233",
cost: 100,
quantity: 0
}
]
index=[]
arr.forEach(x => {
if (x.quantity==0) index.push(arr.indexOf(x))
});
i=0
index.forEach(x=>{
arr.splice(x+i,1)
i--
})
console.log(arr)
Related
I thought I understood how to loop through a dictionary, but my loop is wrong. I try to access the name of each sub item but my code does not work.
Here is what I did:
list = [
{
title: 'Groceries',
items: [
{
id: 4,
title: 'Food',
cost: 540 ,
},
{
id: 5,
title: 'Hygiene',
cost: 235,
},
{
id: 6,
title: 'Other',
cost: 20,
},
],
}];
function calculateCost(){
let total = 0;
Object.keys(list).forEach((k) => { for (i in k.items) { total += i.data; } });
console.log(total);
return total;
}
Your list is an array includes 1 object and this object has two properties title and items the items here is an array of objects each one of these objects has property cost so to calculate the total cost you need to loop through items array, here is how you do it:
let list = [
{
title: 'Groceries',
items: [
{
id: 4,
title: 'Food',
cost: 540 ,
},
{
id: 5,
title: 'Hygiene',
cost: 235,
},
{
id: 6,
title: 'Other',
cost: 20,
},
],
}];
function calculateCost(){
let total = 0;
list[0].items.forEach(el => {
total += el.cost;
})
console.log(total)
return total;
}
calculateCost();
Your list is an Array, not an Object.
Instead of Object.keys() use Array.prototype.reduce:
const calculateCost = (arr) => arr.reduce((tot, ob) =>
ob.items.reduce((sum, item) => sum + item.cost, tot), 0);
const list = [
{
title: 'Groceries',
items: [
{id: 4, title: 'Food', cost: 10},
{id: 5, title: 'Hygiene', cost: 20},
{id: 6, title: 'Other', cost: 30}
]
}, {
title: 'Other',
items: [
{id: 8, title: 'Scuba gear', cost: 39}
],
}
];
console.log(calculateCost(list)); // 99
Expanding on #Roko's and #mmh4all's answers, the following code adds several verification statements to handle cases where a deeply nested property in your data is not what you expect it to be.
const calculateCost = (orders) => {
let listOfCosts = [];
// For each 'order' object in the 'orders' array,
// add the value of the 'cost' property of each item
// in the order to 'listOfCosts' array.
orders.forEach(order => {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
if (!Array.isArray(order.items)) { return; }
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseFloat
const orderCostArr = order.items.map(item =>
isNaN(item.cost) ? 0 : parseFloat(item.cost, 10));
if (orderCostArr.length === 0) { return; }
// Concatenate 'orderCostArr' to the 'listOfCosts' array
//listOfCosts = listOfCosts.concat(orderCostArry);
// Alternate approach is to use the spread syntax (...) to
// push the items in the array returned by 'order.items.map()'
// into the 'listOfCosts' array.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax
listOfCosts.push(...orderCostArr);
});
// Use the 'reduce' method on the 'listOfCosts' array
// to get the total cost.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
const totalCost = listOfCosts.reduce(
(accumulator, currentValue) => accumulator + currentValue, 0);
return totalCost;
};
const list = [
{
title: 'Groceries',
items: [
{ id: 4, title: 'Food', cost: 10 },
{ id: 3, title: 'Baked goods', cost: 20 },
{ id: 5, title: 'Hygiene', cost: 0 },
{ id: 6, title: 'Other' }
]
}, {
title: 'Gear',
items: {},
}, {
title: 'Accessories',
items: [],
}, {
title: 'Bags',
}, {
title: 'Other',
items: [
{ id: 10, title: 'Scuba gear', cost: "5" },
{ id: 8, title: 'Scuba gear', cost: "err" },
{ id: 9, title: 'Scuba gear', cost: 59 }
],
}
];
console.log(calculateCost(list)); // 94
var input = [{id: 1, price: 1200, profit:60, name:'Messi'},
{id: 2, price: 600, profit:40, name:'Ronaldo'},
{id: 1, price: 100, profit:40, name:'Messi'},
{id: 1, price: 200, profit:30, name:'Messi'},
{id: 2, price: 400, profit:10, name:'Ronaldo'},
{id: 1, price: 800, profit:10, name:'Messi'}];
Expected Output:
[{id:1, name:'Messi', price:'2300', profit:'140'},
{id:2, name:'Ronaldo', price:'1000', profit:'50'},
]
Tried:
var output = { };
input.forEach(e => output[e.id] = (output[e.id] || 0) + e.price);
console.log(output);
How to make like the expected output here.
You can do it with the .reduce() method
var input = [{
id: 1,
price: 1200,
profit: 60,
name: 'Messi'
},
{
id: 2,
price: 600,
profit: 40,
name: 'Ronaldo'
},
{
id: 1,
price: 100,
profit: 40,
name: 'Messi'
},
{
id: 1,
price: 200,
profit: 30,
name: 'Messi'
},
{
id: 2,
price: 400,
profit: 10,
name: 'Ronaldo'
},
{
id: 1,
price: 800,
profit: 10,
name: 'Messi'
}
];
/* [{id:1, name:'Messi', price:'2300', profit:'140'},
{id:2, name:'Ronaldo', price:'1000', profit:'50'}] */
var result = []; //Initialize array
//array reduce
input.reduce(function(res, value) {
if (!res[value.name]) {
res[value.name] = {
id: value.id,
name: value.name,
price: 0,
profit: 0
};
result.push(res[value.name])
}
res[value.name].price += value.price; //sums price key values
res[value.name].profit += value.profit; //sums profit key values
return res; //returns response
}, {});
//output
console.log(result)
You can use Array.prototype.reduce() combined with Nullish coalescing assignment (??=)
Code:
const input = [{ id: 1, price: 1200, profit: 60, name: 'Messi' },{ id: 2, price: 600, profit: 40, name: 'Ronaldo' },{ id: 1, price: 100, profit: 40, name: 'Messi' },{ id: 1, price: 200, profit: 30, name: 'Messi' },{ id: 2, price: 400, profit: 10, name: 'Ronaldo' },{ id: 1, price: 800, profit: 10, name: 'Messi' },]
const result = input.reduce((a, c) => {
a[c.id] ??= { id: c.id, name: c.name, price: 0, profit: 0 }
a[c.id].price += c.price
a[c.id].profit += c.profit
return a
}, {})
console.log(Object.values(result))
There are two key things here.
You need to loop over the array of objects.
JavaScript provides several mechanisms for looping over arrays. You can use a traditional for statement. Or a for/of statement, or perhaps reduce as mentioned in the other answers.
You need to be able to group information by the name provided in the objects.
Objects are very useful here as they allow you to associate (read: "group") values with unique keys.
So, the general procedure is:
Initialise an object to use for storing the keys (names) and values (some more objects)
Loop over the input array. Take the name from the object and check to see if it exists as a key in the object. If it doesn't exist add it as a key, and then assign an initial object in the iteration as its value.
Update the values of that object where appropriate
Well, now you have an object of objects where what you want is an array of objects again, similar to your input. Use Object.values to return an array of the object's values (the nested objects).
Note: in your question your required output has the price and profit as strings rather than numbers so you may have to do an additional mapping operation on the array from Object.values to get that result. I've included that code at the end of the example along with some links to documentation of other code mentioned.)
In this example I'll use a for/of loop.
const input=[{id:1,price:1200,profit:60,name:"Messi"},{id:2,price:600,profit:40,name:"Ronaldo"},{id:1,price:100,profit:40,name:"Messi"},{id:1,price:200,profit:30,name:"Messi"},{id:2,price:400,profit:10,name:"Ronaldo"},{id:1,price:800,profit:10,name:"Messi"}];
// Initialise an empty object
const temp = {};
// For every object in the input array...
for (const obj of input) {
// Destructure the properties from it
const { id, price, profit, name } = obj;
// If the name doesn't exist as a key on the object
// add it, and assign an initial object to it that mirrors
// the current object in the iteration, but where the
// values of the properties that you want to increase are
// set to zero. The key is there just go to the next step
temp[name] ??= { id, name, price: 0, profit: 0 };
// Increase the price and profit values in
// the initialised object
temp[name].price += price;
temp[name].profit += profit;
}
// Finally, after the iteration, we return
// an array of those nested objects we've created
const output = Object.values(temp);
console.log(output);
// If you want to strings for those values
// you'll have to do an additional `map` to
// stringify them
const stringified = output.map(obj => {
// Use destructuring to get the profit and
// price properties, and assign everything else to `rest`
const { price, profit, ...rest } = obj;
// Return a new object by spreading out `rest`,
// and coercing the numbers to strings
return {
...rest,
price: price.toString(),
profit: profit.toString()
};
});
console.log(stringified);
Additional information
Destructuring assignment
Nullish coalescing assignment
Rest parameters
Spread syntax
Instead of computing just price, you can also compute profit and also add id and name, the result of each id being an object instead of a number. Then use Object.values() to get the final result. As has been demonstrated elsewhere Array#reduce can also be used to give us the intermediate result.
const input = [{id: 1, price: 1200, profit:60, name:'Messi'},
{id: 2, price: 600, profit:40, name:'Ronaldo'},
{id: 1, price: 100, profit:40, name:'Messi'},
{id: 1, price: 200, profit:30, name:'Messi'},
{id: 2, price: 400, profit:10, name:'Ronaldo'},
{id: 1, price: 800, profit:10, name:'Messi'}];
/*Expected Output:
[{id:1, name:'Messi', price:'2300', profit:'140'},
{id:2, name:'Ronaldo', price:'1000', profit:'50'},
]
Tried:*/
const output = { };
input.forEach(
e => output[e.id] = {
id: e.id,
name: e.name,
price:(output[e.id]?.price || 0) + e.price,
profit:(output[e.id]?.profit || 0) + e.profit
});
console.log(Object.values(output));
Give this a shot :)
var input = [{id: 1, price: 1200, profit:60, name:'Messi'},
{id: 2, price: 600, profit:40, name:'Ronaldo'},
{id: 1, price: 100, profit:40, name:'Messi'},
{id: 1, price: 200, profit:30, name:'Messi'},
{id: 2, price: 400, profit:10, name:'Ronaldo'},
{id: 1, price: 800, profit:10, name:'Messi'}];
function transform(input) {
let output = []
let lookup = {}
for (let i = 0; i < input.length; i++) {
let item = input[i]
let key = item.id
if (lookup[key]) {
lookup[key].price += item.price
lookup[key].profit += item.profit
} else {
lookup[key] = { ...item }
}
}
for (let key in lookup) {
output.push(lookup[key])
}
return output
}
console.log(transform(input))
Hey I am making a food delivery app, and I have a list of data. I want to remove the item if the condition matches:
If the id and subDataId matches, remove that item.
If only the id matches (and I don't have subDataId I can use for a comparison) then remove that item.
Here is my data
state: [
{
id: 1,
quantity: 4,
price: 120,
subDataId: 1,
itemTotalPrice: 480
},
{
id: 1,
quantity: 5,
price: 70,
subDataId: 2,
itemTotalPrice: 350
},
{
id: 2,
quantity: 3,
price: 140,
subDataId: 1,
itemTotalPrice: 420
},
{
id: 2,
quantity: 5,
price: 80,
subDataId: 2,
itemTotalPrice: 400
},
{
id: 3,
quantity: 6,
price: 60,
itemTotalPrice: 360
}
],
Here is my code
let data = {id: 1, subDataId: 2};
// let data ={id: 3}
if (data.subDataId) {
const filtered = state.filter((filterItem) => {
return (
filterItem.id !== data.id && filterItem.subDataId !== data.subDataId
); });
if (filtered.length !== 0) {
return (state = filtered);
} else {
return [...state];
}
} else {
const filtered = state.filter((filterItem) => {
return filterItem.id !== data.id;
});
if (filtered.length !== 0) {
return (state = filtered);
} else {
return [...state];
}
}
The code does not work properly and remove several items instead of one.
EDIT Guys, Guys I want to check if the id and subdDataId matches then remove the item and return an array with the rest of the data and if only the idmatches then do the same.
Try this,
let newState = state.filter((item) =>{
return item.id !== data.id && item.subDataId !== data.subDataId;
});
filterItem.id !== data.id && filterItem.subDataId !== data.subDataId is not correct. You want to remove the item if the id and subDataId matches, i.e. filterItem.id === data.id && filterItem.subDataId === data.subDataId. Therefore, you want to keep the item if !(filterItem.id === data.id && filterItem.subDataId === data.subDataId)
const state = [
{
id: 1,
quantity: 4,
price: 120,
subDataId: 1,
itemTotalPrice: 480
},
{
id: 1,
quantity: 5,
price: 70,
subDataId: 2,
itemTotalPrice: 350
},
{
id: 2,
quantity: 3,
price: 140,
subDataId: 1,
itemTotalPrice: 420
},
{
id: 2,
quantity: 5,
price: 80,
subDataId: 2,
itemTotalPrice: 400
},
{
id: 3,
quantity: 6,
price: 60,
itemTotalPrice: 360
}
];
function filter(data) {
if (data.subDataId) {
const filtered = state.filter((filterItem) =>
!(filterItem.id === data.id && filterItem.subDataId === data.subDataId));
if (filtered.length !== 0) {
return filtered;
} else {
return [...state];
}
} else {
const filtered = state.filter((filterItem) => {
return filterItem.id !== data.id;
});
if (filtered.length !== 0) {
return filtered;
} else {
return [...state];
}
}
}
console.log(filter({id:1, subDataId:2}));
console.log(filter({id:1}));
I guess you are overthinking the problem a little bit. Why not use a simple filter()? In your explanation condition 2 is true as soon as condition 1 is true. So the actual condition is:
item id && subDataId must match the values to be removed.
Try this:
const data = [{
id: 1,
quantity: 4,
price: 120,
subDataId: 1,
itemTotalPrice: 480,
},
{
id: 1,
quantity: 5,
price: 70,
subDataId: 2,
itemTotalPrice: 350,
},
{
id: 2,
quantity: 3,
price: 140,
subDataId: 1,
itemTotalPrice: 420,
},
{
id: 2,
quantity: 5,
price: 80,
subDataId: 2,
itemTotalPrice: 400,
},
{
id: 3,
quantity: 6,
price: 60,
itemTotalPrice: 360,
},
];
const result = data.filter((item) => item.id !== 1 && item.subDataId !== 2);
console.log(result);
This is the solution I came up with from your description. You can run the snippet to check the result.
To filter items with subDataId you have to use || instead of &&.
const state = [
{
id: 1,
quantity: 4,
price: 120,
subDataId: 1,
itemTotalPrice: 480,
},
{
id: 1,
quantity: 5,
price: 70,
subDataId: 2,
itemTotalPrice: 350,
},
{
id: 2,
quantity: 3,
price: 140,
subDataId: 1,
itemTotalPrice: 420,
},
{
id: 2,
quantity: 5,
price: 80,
subDataId: 2,
itemTotalPrice: 400,
},
{
id: 3,
quantity: 6,
price: 60,
itemTotalPrice: 360,
},
];
function filterItem(data, itemToRemove) {
let filteredData = [...data];
// we are checking if itemToRemove has subDataId
if (itemToRemove.subDataId) {
// we are only taking an item if it's id or subDataId doesn't match with itemToRemove's id or subDataId
filteredData = data.filter(
(item) =>
item.id !== itemToRemove.id || item.subDataId !== itemToRemove.subDataId
);
} else {
// if itemToRemove doesn't have subDataId we are only taking an item if it's id doesn't match with itemToRemove's id
filteredData = data.filter((item) => item.id !== itemToRemove.id);
}
return filteredData;
}
const item1 = { id: 1};
const item2 = { id: 1, subDataId: 1 };
console.log('Without subDataId', filterItem(state, item1));
console.log('With subDataId', filterItem(state, item2));
It will check if id and subDataId matches with data or just id matches with data.
const filteredArary = state.filter(item => !((item.id === data.id && item.subDataIdd === data.subDataId) || item.id === data.id))
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I am making a food delivery app and I have two different array of objects. One of them is cartItems and the other is foodItems. The arrays can be of different sizes. So what do I want to loop over each array and check
if the ids of both the array match.
Note I want to check if the quantity exists then increment it by the new quantity else simply add a new quantity
check if itemDetails exists in foodItems array and if it exists, check if the price of cartItems matches of that foodItem, then update the cartItems object, else remove them.
if itemDetails does not exist then update the quantity of the item.
Update
If there are two items with similar id and price, the quantities should be added
Here is my cartItems:
let cartItems = [
{ id: 1, price: 120, quantity: 7 },
{ id: 2, price: 70, quantity: 4 },
{ id: 1, price: 70, quantity: 3 },
{ id: 3, price: 60, quantity: 1 },
{id: 1, price: 120, quantity: 2}
];
Here is my foodItems
let foodItems = [
{
id: 1,
name: "chicken",
itemDetails: [
{
price: 120,
details: "2 pcs of chicken biryani"
},
{
price: 70,
details: "1 pcs of chicken biryani"
}
],
},
{
id: 2,
name: "Mutton",
itemDetails: [
{
price: 120,
details: "Two pieces of mutton biryani",
},
{
price: 70,
details: "one pcs of mutton biryani"
},
],
},
{ id: 3, name: "Ice Cream", price: 60 },
];
This is my desired output
let filteredArrayOuput = [
{
id: 1,
name: "Chicken Biryani",
itemDetails: [
{
price: 120,
details: "Two pieces of chicken Biryani",
},
],
quantity: 7,
},
{
id: 2,
name: "Mutton Biryani",
itemDetails: [
{
price: 70,
details: "Two pieces of mutton biryani",
},
],
quantity: 4,
},
{
id: 1,
price: "Chicken Biryani",
quantity: 3,
itemDetails: [
{
price: 70,
details: "Two pieces of Chicken Biryani",
},
],
},
{ id: 3, price: 60, quantity: 1 },
];
This is what I have done till now
const filterFunc = (arr, price) => {
let filtered = arr.filter((item) => {
return item.price == price;
});
return filtered;
};
const filterArray = (arr1, arr2) => {
const filtered = arr2.filter((el) => {
let arr = arr1.find(({ id, quantity, price }) => {
if (el.id === id) {
if (el.itemDetails !== undefined && el.itemDetails.length !== 0) {
let itemDetails = el.itemDetails;
return (
(el.quantity = quantity),
(el.itemDetails = filterFunc(itemDetails, price))
);
} else {
return (el.quantity = quantity);
}
}
});
return arr;
});
return filtered;
};
console.log(filterArray(cartItems, foodItems))
You can check the below code.
Find existingFoodItem from FoodItems array
Find priceObj by comparing price
return new object with price details if itemDetails exists (checking with ?), else without price if no itemDetails exists.
let cartItems = [
{ id: 1, price: 120, quantity: 7 },
{ id: 1, price: 120, quantity: 1 },
{ id: 2, price: 70, quantity: 4 },
{ id: 1, price: 70, quantity: 3 },
{ id: 3, price: 60, quantity: 1 },
];
let foodItems = [
{
id: 1,
name: "chicken",
itemDetails: [
{
price: 120,
details: "2 pcs of chicken biryani"
},
{
price: 70,
details: "1 pcs of chicken biryani"
}
],
},
{
id: 2,
name: "Mutton",
itemDetails: [
{
price: 120,
details: "Two pieces of mutton biryani",
},
{
price: 70,
details: "one pcs of mutton biryani"
},
],
},
{ id: 3, name: "Ice Cream", price: 60 },
];
let result = [];
cartItems.forEach(cart => {
let esitingItem = result.find(r => r.id === cart.id && r.itemDetails.find(i => i.price === cart.price));
if(esitingItem){
esitingItem.quantity += cart.quantity;
return;
}
let existingFoodItem = foodItems.find(food => food.id === cart.id);
if(existingFoodItem){
let priceObj = existingFoodItem.itemDetails?.find(item => item.price === cart.price);
if(priceObj){
result.push({id:cart.id,name:existingFoodItem.name,itemDetails:[{...priceObj}],quantity:cart.quantity});
}
else{
return result.push({id:cart.id,name:existingFoodItem.name,quantity:cart.quantity});
}
}
});
console.log(result);
How can I merge my array of objects with same value? I have got orders array, which may have the same product. If so, I want to merge them and add the quantity.
var orders = [
{
product: "chair",
quantity: 5,
price: 900,
},
{
product: "chair",
quantity: 2,
price: 900,
},
]
Expected output:
orders = [
{
product: "chair",
quantity: 7,
price: 900,
}
]
Goal: Group object array by product and add the quantity.
Here is one of the performant way to achieve that:
var orders = [
{
product: "chair",
quantity: 5,
price: 900,
},
{
product: "chair",
quantity: 2,
price: 900,
},
];
const resultTest = {};
const result = [];
orders.forEach((item) => {
if (resultTest[item.product]) {
const index = resultTest[item.product] -1;
const foundItem = result[index];
const newValue = {
...foundItem,
quantity: foundItem.quantity + item.quantity,
};
result[index] = newValue;
} else {
resultTest[item.product] = result.length + 1;
result.push(item);
}
});
console.log(result);
I think you can do this like ths
var orders = [
{
product: "chair",
quantity: 5,
price: 900,
},
{
product: "chair",
quantity: 2,
price: 900,
},
]
var output=new Array;
orders.forEach(elem=>{
var found =false;
for(var i =0; i<output.length;i++)
{
if(output[i].product==elem.product)
{
output[i].quantity+=elem.quantity;
var found = true;
break;
}
}
if(!found)
{
output.push(elem);
}
})
console.log(output);
Here is my solution in more cleaner way:
var orders = [
{
product: "chair",
quantity: 5,
price: 900,
},
{
product: "chair",
quantity: 2,
price: 900,
},
{
product: "table",
quantity: 1,
price: 1000,
}
]
const combineSimilarOrders = {};
orders.forEach((order) => {
if (!(order.product in combineSimilarOrders)) {
combineSimilarOrders[order.product] = [ { ...order } ]
}
else {
if (order.product in combineSimilarOrders) {
let product = Object.keys(combineSimilarOrders);
combineSimilarOrders[product][0].quantity += order.quantity;
combineSimilarOrders[product][0].price += order.price;
}
else {
combineSimilarOrders[order.product].push(order);
}
}
});
console.log(combineSimilarOrders);
Output:
{
chair: [ { product: 'chair', quantity: 7, price: 1800 } ],
table: [ { product: 'table', quantity: 1, price: 1000 } ]
}