how to combine duplicated object in array - javascript

I got an array like this
let p = [
{
sku: 12,
data: { name: 'pro', price: 100 },
},
{
sku: 33,
data: { name: 'pro', price: 100 },
},
{
sku: 55,
data: { name: 'pro', price: 100 },
},
{
sku: 12,
data: { name: 'pro', price: 100 },
},
]
I want to combine the duplicated item, and add extra quantity key in each object
So I will have array like this
p = [
{
sku: 12,
data: { name: 'pro', price: 100 },
quantity:2
},
{
sku: 33,
data: { name: 'so', price: 98 },
quantity:1
},
{
sku: 55,
data: { name: 'do', price: 77 },
quantity:1
},
]
How to do this?

You can use Arary.reduce() to iterate over array and create a new one based on calculations like following:
let p = [
{
sku: 12,
data: { name: 'pro', price: 100 },
},
{
sku: 33,
data: { name: 'pro', price: 100 },
},
{
sku: 55,
data: { name: 'pro', price: 100 },
},
{
sku: 12,
data: { name: 'pro', price: 100 },
},
];
var reducedArray = p.reduce((acc,item) => {
var previousItem = acc.find(findItem => findItem.sku === item.sku);
if(!previousItem){
acc.push({...item, quantity: 1})
}else{
previousItem.quantity++
}
return acc;
},[]);
console.log(reducedArray);
Hope this helps.

You can use JavaScript's reduce() method to do that.
let p = [
{
sku: 12,
data: { name: 'pro', price: 100 },
},
{
sku: 33,
data: { name: 'pro', price: 100 },
},
{
sku: 55,
data: { name: 'pro', price: 100 },
},
{
sku: 12,
data: { name: 'pro', price: 100 },
},
];
let result = p.reduce((arr, currentValue) => {
const index = arr.findIndex(item => item.sku === currentValue.sku);
if (index === -1) {
currentValue.quantity = 1;
arr.push(currentValue);
} else {
arr[index].quantity++;
}
return arr;
}, []);
console.log(result);

Related

Javascript how to merge objects with same product id and summarize quantity

I have a cart with a bunch of products, based on this array:
[
{
product_id: 123,
price: 100,
quantity: 1,
item: { ... some more data }
},
{
product_id: 200,
price: 199,
quantity: 1,
item: { ... some more data }
},
{
product_id: 123,
price: 100,
quantity: 2,
item: { ... some more data }
},
etc...
]
So, when a product has been added multiple times, it should "merge" them into one object and the output to be like:
[
{
product_id: 123,
price: 100,
**quantity: 2,** // THIS IS VERY IMPORTANT
item: { ... some more data }
},
{
product_id: 200,
price: 199,
quantity: 1,
item: { ... some more data }
},
]
So, I've tried the following:
const output = Object.values(
items.reduce((accu, { product_id, ...item }) => {
if (!accu[product_id]) accu[product_id] = {}
accu[product_id] = { product_id, ...accu[product_id], ...item }
return accu
}, {}),
)
this actually gives me what I want, EXCEPT that the quantity is summarized.
How can I achieve that?
You have to add the accumulation logic to the quant separately
like the following example
const cart = [
{
product_id: 123,
price: 100,
quantity: 1,
},
{
product_id: 200,
price: 199,
quantity: 1,
},
{
product_id: 123,
price: 100,
quantity: 2,
},
]
const output = Object.values(
cart.reduce((accu, { product_id, ...item }) => {
if (!accu[product_id]) accu[product_id] =
{
quantity:0
}
accu[product_id] = {
product_id,
...accu[product_id],
...item,
quantity: accu[product_id].quantity + item.quantity // custom accu for quant
}
return accu;
}, {}),
)
console.log(output)

Merge item in array of object with the same ID on Javascript

this is how the object look:
let data = [
{
brandId: '12345',
brand: 'Adidas',
item: {
name: 'Adidas 1',
price: '200',
},
},
{
brandId: '12345',
brand: 'Adidas',
item: {
name: 'Adidas 2',
price: '230',
},
},
{
brandId: '7878',
brand: 'Nike',
item: {
name: 'Nike 1',
price: '305',
},
}
];
i want the item object will merge if the object have the same brandID :
let data = [
{
brandId: '12345',
brand: 'Adidas',
item: [
{
name: 'Adidas 1',
price: '200',
},
{
name: 'Adidas 2',
price: '230',
},
],
},
{
brandId: '7878',
brand: 'Nike',
item: {
name: 'Nike 2',
price: '316',
},
},
];
is there any javascript syntax or method to do this ? and with an explanation will be very nice, Thank You
(Assuming that your output is just a typo and name/price doesn't actually changes) You can use array reduce
let data = [
{
brandId: '12345',
brand: 'Adidas',
item: {
name: 'Adidas 1',
price: '200',
},
},
{
brandId: '12345',
brand: 'Adidas',
item: {
name: 'Adidas 2',
price: '230',
},
},
{
brandId: '7878',
brand: 'Nike',
item: {
name: 'Nike 1',
price: '305',
},
}
];
const mergedItems = data.reduce((acc, curr) => {
// check if current exist on the accumulator
const exist = acc.find(brand => brand.brandId === curr.brandId);
// if it does, add the item on it
if (exist) {
return acc.map((brand) => {
if (brand.brandId === exist.brandId) {
return {
...brand,
item: brand.item.concat(curr.item),
}
}
})
}
// if it doesnt, add it on accumulator, and make the item array
return acc.concat({
...curr,
item: [
curr.item
]
})
})
(I wrote the code manually and not tested)
You can simply achieve this result using Map
let data = [
{
brandId: "12345",
brand: "Adidas",
item: {
name: "Adidas 1",
price: "200",
},
},
{
brandId: "12345",
brand: "Adidas",
item: {
name: "Adidas 2",
price: "230",
},
},
{
brandId: "7878",
brand: "Nike",
item: {
name: "Nike 1",
price: "305",
},
},
];
const dict = new Map();
data.forEach((o) => {
dict.get(o.brandId)
? dict.get(o.brandId).item.push(o.item)
: dict.set(o.brandId, { ...o, item: [o.item] });
});
const result = [];
for (let [k, v] of dict) {
v.item.length === 1 ? result.push({ ...v, item: v.item[0] }) : result.push(v);
}
console.log(result);
/* This is not a part of answer. It is just to give the output fill height. So IGNORE IT */
.as-console-wrapper { max-height: 100% !important; top: 0; }

How to create a nested array of object from an array of objects

How Can I loop through this array of objects and change it so that the individual menu items are nested in the object menu_name?
const menus = [
{ menu_name: 'Entre', id:0 },
{
name: 'Soup',
price: 14.99,
id:1
},
{
name: 'Chips & Salsa',
price: 7.99,
id:2
},
{
name: 'Chicken Nuggets',
price: 12.99,
id:3
},
{ menu_name: 'Sides', id:4 },
{
name: 'Fries',
price: 4.99,
id:5
},
{
name: 'Drinks',
price: 2.99,
id:6
},
{
name: 'Onion Rings',
price: 5.99,
id:7
},
];
the end result should look like this for each menu_name object, where an array of menus is nested in the menu_name object
{
menu_name: 'Sides',
menu: [
{
name: 'Fries',
price: 4.99,
},
{
name: 'Drinks',
price: 2.99,
},
{
name: 'Onion Rings',
price: 5.99,
},
],
},
You can easily achieve this using reduce and object destructuring
const menus = [
{ menu_name: "Entre", id: 0 },
{
name: "Soup",
price: 14.99,
id: 1,
},
{
name: "Chips & Salsa",
price: 7.99,
id: 2,
},
{
name: "Chicken Nuggets",
price: 12.99,
id: 3,
},
{ menu_name: "Sides", id: 4 },
{
name: "Fries",
price: 4.99,
id: 5,
},
{
name: "Drinks",
price: 2.99,
id: 6,
},
{
name: "Onion Rings",
price: 5.99,
id: 7,
},
];
const result = menus.reduce((acc, curr) => {
const { menu_name } = curr;
if (menu_name) {
acc.push({ menu_name, menu: [] });
} else {
const { name, price } = curr;
acc[acc.length - 1].menu.push({ name, price });
}
return acc;
}, []);
console.log(result);
var newMenu = [];
menus.forEach(menu=>{
if(menu.menu_name){
newMenu.push({...menu, menu: []})
}else{
newMenu[newMenu.length-1].menu.push(menu)
}
});

How to insert entries from into a nested JavaScript Object

I'm facing trouble in making a nested insertion of a particular entry into my data structure. The 'positionValue' in the 'data' object below has to be inserted into 'mystructure' based on whether it is Team1 or Team2, and based on the category 'Lombard Loans/Time Deposits/Demand Deposits' and then further based on 'name' of the product (the last nested structure).
The original object:
data: [
{
balanceSheetPositionResults: [
{
positionValue: 12,
balanceSheetPosition: {
name: "asset_bc_lombard_a_onsight",
category: "LOMBARD_LOANS",
type: "ASSET"
},
},
{
positionValue: 58,
balanceSheetPosition: {
name: "liability_bc_timedeposits",
category: "TIME_DEPOSITS",
type: "ASSET"
},
},
{
positionValue: 58,
balanceSheetPosition: {
name: "liability_bc_demanddeposits",
category: "DEMAND_DEPOSITS",
type: "ASSET"
},
},
{
positionValue: 10,
balanceSheetPosition: {
name: "asset_bc_lombard_a_lt1m",
category: "LOMBARD_LOANS",
type: "ASSET"
},
}
],
bank: {
name: "Team1"
},
game: {
name: "TestGame"
},
bsSum: 2,
period: {
index: 1
},
},
{
balanceSheetPositionResults: [
{
positionValue: 12,
balanceSheetPosition: {
name: "asset_bc_lombard_a_onsight",
category: "LOMBARD_LOANS",
type: "ASSET"
},
},
{
positionValue: 58,
balanceSheetPosition: {
name: "liability_bc_timedeposits",
category: "TIME_DEPOSITS",
type: "ASSET"
},
},
{
positionValue: 58,
balanceSheetPosition: {
name: "liability_bc_demanddeposits",
category: "DEMAND_DEPOSITS",
type: "ASSET"
},
},
{
positionValue: 10,
balanceSheetPosition: {
name: "asset_bc_lombard_a_lt1m",
category: "LOMBARD_LOANS",
type: "ASSET"
},
}
],
bank: {
name: "Team2"
},
game: {
name: "TestGame"
},
bsSum: 2,
period: {
index: 1
}
}
]
The structure that I made after some transformation (this is just a snippet):
{ mystructure:
[
{ name: 'Team2',
LOMBARD_LOANS:
[ { name: 'asset_bc_lombard_a_onsight'
},
{ name: 'asset_bc_lombard_a_lt1m'
}
],
DEMAND_DEPOSITS:
[ { name: 'liability_bc_demanddeposits'
}
],
TIME_DEPOSITS:
[ { name: 'liability_bc_timedeposits'
}
]
},
{ name: 'Team1',
LOMBARD_LOANS:
[ { name: 'asset_bc_lombard_a_onsight'
},
{ name: 'asset_bc_lombard_a_lt1m'
}
],
DEMAND_DEPOSITS:
[ { name: 'liability_bc_demanddeposits'
}
],
TIME_DEPOSITS:
[ { name: 'liability_bc_timedeposits'
}
]
}
]
}
The result that would look like:
{ mystructure:
[
{ name: 'Team2',
LOMBARD_LOANS:
[ { name: 'asset_bc_lombard_a_onsight',
positionValue: 12
},
{ name: 'asset_bc_lombard_a_lt1m',
positionValue: 58
}
],
DEMAND_DEPOSITS:
[ { name: 'liability_bc_demanddeposits',
positionValue: 58
}
],
TIME_DEPOSITS:
[ { name: 'liability_bc_timedeposits',
positionValue: 10
}
]
},
{ name: 'Team1',
LOMBARD_LOANS:
[ { name: 'asset_bc_lombard_a_onsight',
positionValue: 12
},
{ name: 'asset_bc_lombard_a_lt1m',
positionValue: 58
}
],
DEMAND_DEPOSITS:
[ { name: 'liability_bc_demanddeposits',
positionValue: 58
}
],
TIME_DEPOSITS:
[ { name: 'liability_bc_timedeposits',
positionValue: 10
}
]
}
]
}
Assuming each bank name comes only once, pass your original array to this transformer :
function transformData(data) {
return data.map(entry => {
const loanType = {};
entry.balanceSheetPositionResults.forEach(balanceEntry => {
const { name, category, type } = balanceEntry.balanceSheetPosition;
if (!(category in loanType)) {
loanType[category] = [];
}
loanType[category].push({
name,
positionValue: balanceEntry.positionValue
});
});
return {
name: entry.bank.name,
...loanType
};
});
}

Javascript Multidimensional Array Key-Value

I am doing an AJAX request to a JSON and getting following code as response:
{
total: "1",
items: [
{
id: 43,
title: "ThisIsTheTitle",
promoted: false,
sticky: false,
weight: 10,
created: {
timestamp: 1482054,
formatted: "17/01/2017"
},
url: "http://...",
airdate: {
timestamp: 1484980,
formatted: "17/01/2017"
},
video: {
id: 43,
number_of_views: 1,
duration: {
seconds: 50,
formatted: "00:00"
},
required_login: false
},
program: {
id: 25,
url: "http://...",
title: "ProgrammaTitel"
},
image: {
uri: "public://...",
full: "http://..."
},
tags: [
{
id: "4",
name: "Map"
},
{
id: "7",
name: "Aflevering2"
}
]
}
]
}
Now I push this data into my own JSArray. Note there is now only 1 response-item but more will be added.
I want to retrieve specific object-data based on the name of a tag of the object (item > tags > name = 'Aflevering2')
So I would like the data from the object where the tag name is 'Aflevering2'.
Any advice? Thanks!
You can find the items with a combination of filter() and some():
obj.items.filter(v => v.tags.some(k => k.name === 'Aflevering2'));
let obj = {
total: "1",
items: [
{
id: 43,
title: "ThisIsTheTitle",
promoted: false,
sticky: false,
weight: 10,
created: {
timestamp: 1482054,
formatted: "17/01/2017"
},
url: "http://...",
airdate: {
timestamp: 1484980,
formatted: "17/01/2017"
},
video: {
id: 43,
number_of_views: 1,
duration: {
seconds: 50,
formatted: "00:00"
},
required_login: false
},
program: {
id: 25,
url: "http://...",
title: "ProgrammaTitel"
},
image: {
uri: "public://...",
full: "http://..."
},
tags: [
{
id: "4",
name: "Map"
},
{
id: "7",
name: "Aflevering2"
}
]
}
]
}
let items = obj.items.filter(v => v.tags.some(k => k.name === 'Aflevering2'));
console.log(items);

Categories