I have an object of object
cart {
KDR010011: {
barcode: "0"
brand: "Kapal Api"
category: "KEBUTUHAN DAPUR"
cost_price: "107569.66490299824"
cost_price_per_piece: 896.413874191652
name: "Kapal Api 25g sp mix"
product_id: "KDR010011"
qty: 1
qty_per_box: 120
selling_price: 116000
selling_price_per_piece: 962.5
},
KDR010125: {
barcode: ""
brand: "Kapal Api"
category: "KEBUTUHAN DAPUR"
cost_price: "110317.63859070961"
cost_price_per_piece: 835.7396862932546
name: "ABC Susu 31g"
product_id: "KDR010125"
qty: 5
qty_per_box: 132
selling_price: 113000
selling_price_per_piece: 863.6363636363636
}
}
and I want to remove the property, the result what I want:
cart {
KDR010011: {
qty: 1
selling_price: 116000
},
KDR010125: {
qty: 5
selling_price: 113000
}
}
I am using underscore js library, the result is this:
What should I do?
You can achieve this easily by looping over the keys of the object and assigning the value for each key back to the original object. If you don't want to modify the original object just assign the keys to a new one.
Personally I'd change my data structure so that the cart was an array of objects and each object had the KDR010011 key as a property instead.
const obj = {
KDR010011: {
barcode: "0",
brand: "Kapal Api",
category: "KEBUTUHAN DAPUR",
cost_price: "107569.66490299824",
cost_price_per_piece: 896.413874191652,
name: "Kapal Api 25g sp mix",
product_id: "KDR010011",
qty: 1,
qty_per_box: 120,
selling_price: 116000,
selling_price_per_piece: 962.5,
},
KDR010125: {
barcode: "",
brand: "Kapal Api",
category: "KEBUTUHAN DAPUR",
cost_price: "110317.63859070961",
cost_price_per_piece: 835.7396862932546,
name: "ABC Susu 31g",
product_id: "KDR010125",
qty: 5,
qty_per_box: 132,
selling_price: 113000,
selling_price_per_piece: 863.6363636363636,
}
}
Object.keys(obj).forEach(key => obj[key] = {
qty: obj[key].qty,
selling_price: obj[key].selling_price,
})
console.log(obj)
You can try this:
const newCart = {...cart}
Object.keys(newCart).forEach(key => {
newCart[key] = {
qty: newCart[key].qti,
selling_price: newCart[key].sailing_price
}
}
You need commas in your object
I have a feeling I could use destructuring better than here
const cart = {
KDR010011: {
barcode: "0",
brand: "Kapal Api",
category: "KEBUTUHAN DAPUR",
cost_price: "107569.66490299824",
cost_price_per_piece: 896.413874191652,
name: "Kapal Api 25g sp mix",
product_id: "KDR010011",
qty: 1,
qty_per_box: 120,
selling_price: 116000,
selling_price_per_piece: 962.5
},
KDR010125: {
barcode: "",
brand: "Kapal Api",
category: "KEBUTUHAN DAPUR",
cost_price: "110317.63859070961",
cost_price_per_piece: 835.7396862932546,
name: "ABC Susu 31g",
product_id: "KDR010125",
qty: 5,
qty_per_box: 132,
selling_price: 113000,
selling_price_per_piece: 863.6363636363636
}
}
let newCart = {}
Object.keys(cart).forEach(key => newCart[key] = { qty: cart[key].qty, selling_price : cart[key].selling_price })
console.log(newCart)
Related
This question already has answers here:
Group objects by property in javascript
(8 answers)
Closed 2 months ago.
i have array of object transaction join with product and user table, i want to combine id with same value so it can display two different data in 1 object
Here's my data
let test = [
{
TransactionId: 1, //transaction table
username: "A", //user table
qty: 3, //product table
product_name: "Logitech G733",
price: $100,
description: "Lalalalala",
productId: 10
},
{
TransactionId: 2,
username: "B",
qty: 1,
product_name: "Razer",
price: $200,
description: "Blalalala",
productId: 12
},
{
TransactionId: 1,
username: "A",
qty: 1,
product_name: "Mousepad",
price: $50,
description: "This is mousepad",
productId: 7
},
{
TransactionId: 3,
username: "C",
qty: 2,
product_name: "Headphone",
price: $300,
description: "This is Headphone",
productId: 2
},
]
this is the output i want
let test = [
{
TransactionId: 1,
username: "A",
qty: [3, 1],
product_name: ["Logitech G733", "Mousepad"],
price: [$100, $50]
description: ["Lalalalala", "This is mousepad"],
productId: [10, 7]
},
{
TransactionId: 2,
username: "B",
qty: 1,
product_name: "Razer",
price: $200,
description: "Blalalala",
productId: 12
},
{
TransactionId: 3,
username: "C",
qty: 2,
product_name: "Headphone",
price: $300,
description: "This is Headphone",
productId: 2
},
]
i tried using reduce and Object.assign but the output only shows object with "Mousepad" not make array ["logitech G733","Mousepad"]
there should be many ways to do it, I used a map to combine the transactions and you can do whatever you need for the map after. For example
const test = [
{
TransactionId: 1, //transaction table
username: "A", //user table
qty: 3, //product table
product_name: "Logitech G733",
price: 100,
description: "Lalalalala",
productId: 10
},
{
TransactionId: 2,
username: "B",
qty: 1,
product_name: "Razer",
price: 200,
description: "Blalalala",
productId: 12
},
{
TransactionId: 1,
username: "A",
qty: 1,
product_name: "Mousepad",
price: 50,
description: "This is mousepad",
productId: 7
},
{
TransactionId: 3,
username: "C",
qty: 2,
product_name: "Headphone",
price: 300,
description: "This is Headphone",
productId: 2
},
]
const tMap = new Map();
test.forEach(transation => {
tMap.set(transation.TransactionId, { ...tMap.get(transation.TransactionId), ...transation });
})
If you wan to deep combined you can use some tool like lodash deep merge
tMap.set(transation.TransactionId, _.merge(tMap.get(transation.TransactionId), transation))
Then you have a map based on your tranastion Id, and you can decide what to do next. If you wan the array back you can simple run
console.log(Array.from(tMap.values()));
Say I have the following dataLayer:
{
ecommerce: {
currencyCode: "USD",
purchase: {
actionField: {
id: "1a6d5021",
affiliation: "Online Store",
revenue: 40,
tax: 0,
shipping: "",
coupon: ""
},
products: [
{
name: "Product 1",
id: "123",
price: 40,
category: null,
quantity: 1,
coupon: "disc10",
type: "Service A"
},
{
name: "Product 4",
id: "456",
price: 40,
category: null,
quantity: 1,
coupon: "disc10",
type: "Service B"
}
]
}
}
}
So in the product array, category always has value null. How can I push the same value as type respectively for each product, whilst leaving everything else in the dataLayer untouched?
Ultimately the final result that I am trying to achieve would be like this:
{
ecommerce: {
currencyCode: "USD",
purchase: {
actionField: {
id: "1a6d5021",
affiliation: "Online Store",
revenue: 40,
tax: 0,
shipping: "",
coupon: ""
},
products: [
{
name: "Product 1",
id: "123",
price: 40,
category: "Service A",
quantity: 1,
coupon: "disc10",
type: "Service A"
},
{
name: "Product 4",
id: "456",
price: 40,
category: "Service B",
quantity: 1,
coupon: "disc10",
type: "Service B"
}
]
}
}
}
It be easy with a single product, but I quite can't find how to do it when multiple products.
Thanks in advance for your help.
If I understand your requirement correctly that you want to assign the type value in the category for each products object. If Yes, Its a straight forward.
Working Demo :
const productObj = {
ecommerce: {
currencyCode: "USD",
purchase: {
actionField: {
id: "1a6d5021",
affiliation: "Online Store",
revenue: 40,
tax: 0,
shipping: "",
coupon: ""
},
products: [{
name: "Product 1",
id: "123",
price: 40,
category: null,
quantity: 1,
coupon: "disc10",
type: "Service A"
},
{
name: "Product 4",
id: "456",
price: 40,
category: null,
quantity: 1,
coupon: "disc10",
type: "Service B"
}
]
}
}
};
productObj.ecommerce.purchase.products.forEach((obj) => obj.category = obj.type);
console.log(productObj);
There are two options.
Push the whole ecommerce object again, with all fields set now. It results in a bit of a mess in DL and certain timing issues one has to keep in mind when implementing tracking.
Remove/delay the first ecommerce push till you have all info and only push the ecommerce object once.
In most cases, 2 is the best option. 1 can be justified when the event relying on the ecommerce object has to fire before categories become available to the front-end.
Try
function createCategoryFn(category) {
return (properties) => {
return {
name: "",
id: "",
price: 0,
category: category,
quantity: 1,
coupon: "",
type: category,
...properties
};
};
}
const createSportsProduct = createCategoryFn('Sports');
const tennisProduct = createSportsProduct({ name: 'tennis racket', id: 1, price: 100 });
const basketballProduct = createSportsProduct({ name: 'basketball', id: 2, price: 100 });
console.log(tennisProduct);
console.log(basketballProduct)
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)
}
});
I would like to populate the value 'discount' for a product with the discount ID value from the array discounts, if the respective product ID exists as a value in the Discounts object.
const products = [{
id: "05cdb75d-7984-4dbf-b0f4-d6532163b66d",
name: "SANTO - Schnürstiefelette",
price: 199.95,
discount: 0,
},
{
id: "1b9b6c7e-c856-464c-ba64-98c9dd6733b5",
name: "AIR FORCE 1 07 LV8 - Sneaker low",
price: 109.95,
discount: 0,
},
{
id: "f831aaf4-347a-458f-bb0c-21cf02aeac2e",
name: "DUFF 9.0 - Sporttasche",
price: 34.95,
discount: 0,
},
{
id: "471ad894-150b-4a2b-881c-a9a4dbc4b401",
name: "Strickpullover",
price: 20.99,
discount: 0,
},
];
const discounts = [{
id: "5791ae04-a704-4f44-808b-de5ddb8812b5",
name: "Christmas discount",
productIds: ["1b9b6c7e-c856-464c-ba64-98c9dd6733b5", "f831aaf4-347a-458f-bb0c-21cf02aeac2e"],
active: true
},
{
id: "5791ae04-a704-4f44-808b-de5ddb8812e6",
name: "Christmas discount 2",
productIds: ["05cdb75d-7984-4dbf-b0f4-d6532163b66d"],
active: true
}
];
At the end i need it like:
const products = [{
id: "05cdb75d-7984-4dbf-b0f4-d6532163b66d",
name: "SANTO - Schnürstiefelette",
price: 199.95,
discount: '5791ae04-a704-4f44-808b-de5ddb8812e6',
},
...
...
You could use map() to transform products array. And find() and includes() to check if discount exists for a product.
const products = [{ id: "05cdb75d-7984-4dbf-b0f4-d6532163b66d", name: "SANTO - Schnürstiefelette", price: 199.95, discount: 0, }, { id: "1b9b6c7e-c856-464c-ba64-98c9dd6733b5", name: "AIR FORCE 1 07 LV8 - Sneaker low", price: 109.95, discount: 0, }, { id: "f831aaf4-347a-458f-bb0c-21cf02aeac2e", name: "DUFF 9.0 - Sporttasche", price: 34.95, discount: 0, }, { id: "471ad894-150b-4a2b-881c-a9a4dbc4b401", name: "Strickpullover", price: 20.99, discount: 0, }, ];
const discounts = [{ id: "5791ae04-a704-4f44-808b-de5ddb8812b5", name: "Christmas discount", productIds: ["1b9b6c7e-c856-464c-ba64-98c9dd6733b5", "f831aaf4-347a-458f-bb0c-21cf02aeac2e"], active: true }, { id: "5791ae04-a704-4f44-808b-de5ddb8812e6", name: "Christmas discount 2", productIds: ["05cdb75d-7984-4dbf-b0f4-d6532163b66d"], active: true } ];
let result = products.map(product => {
let discount = discounts.find(item => item.productIds.includes(product.id));
return {
...product,
"discount": discount ? discount.id : product.discount
};
});
console.log(result);
You could store the discounts in a Map and map the object with a new discount object, if necessary.
var products = [{ id: "05cdb75d-7984-4dbf-b0f4-d6532163b66d", name: "SANTO - Schnürstiefelette", price: 199.95, discount: 0 }, { id: "1b9b6c7e-c856-464c-ba64-98c9dd6733b5", name: "AIR FORCE 1 07 LV8 - Sneaker low", price: 109.95, discount: 0 }, { id: "f831aaf4-347a-458f-bb0c-21cf02aeac2e", name: "DUFF 9.0 - Sporttasche", price: 34.95, discount: 0 }, { id: "471ad894-150b-4a2b-881c-a9a4dbc4b401", name: "Strickpullover", price: 20.99, discount: 0 }],
discounts = [{ id: "5791ae04-a704-4f44-808b-de5ddb8812b5", name: "Christmas discount", productIds: ["1b9b6c7e-c856-464c-ba64-98c9dd6733b5", "f831aaf4-347a-458f-bb0c-21cf02aeac2e"], active: true }, { id: "5791ae04-a704-4f44-808b-de5ddb8812e6", name: "Christmas discount 2", productIds: ["05cdb75d-7984-4dbf-b0f4-d6532163b66d"], active: true }],
ids = discounts.reduce((m, { id, productIds }) => productIds.reduce((n, pid) => n.set(pid, id), m), new Map);
products = products.map(p => Object.assign({}, p, ids.has(p.id) && { discount: ids.get(p.id) }));
console.log(products);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nested loop through both products and discounts array, if the product id is included inside the productIds array of any of the objects in the discounts array, assign the discount id to the product discount.
for (let product of products) {
for (let discount of discounts) {
if (discount.productIds.includes(product.id)){
product.discount = discount.id;
break;
}
}
}
I have an object with the below structure and I'm wondering how to add a line to it.
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
line to add:
'3': { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" },
and I would like to add another line to this array but I have no clue how to even start so any help is welcome!
I assume you need to calculate the next insertion point.
Not sure why you're not using an actual Array, but if you have a fixed offset from 0 and a sequential enumeration from there, you can use Object.keys to get the number of keys for the next index.
const offset = 1;
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
itemList[Object.keys(itemList).length + offset] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" }
console.log(itemList);
But again, this presumes there's some good reason for using this kind of data structure instead of an Array.
And note that the offset can be pre-calculated if it's not known in advance, again assuming the rest of the keys are sequential integers.
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
const offset = Math.min(Object.keys(itemList).length, ...Object.keys(itemList));
itemList[Object.keys(itemList).length + offset] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" }
console.log(itemList);
Or if you don't have a sequential set of numeric keys, but need to add one after the current highest key, you can do this:
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
const next = Math.max(-1, ...Object.keys(itemList)) + 1;
itemList[next] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" }
console.log(itemList);
Surprised none of the other answers have simply suggested switched to an actual array (of objects), because then you could simply push a new object into it.
You can then take advantage of all the useful array methods that are available to change/filter your data.
var itemList = [
{ type: "car", make: "audi", price: 500, number: 10, description: "a car" },
{ type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
];
const newItem = { type: "kite", make: "adobe", price: 10, number: 12, description: "Woo!" }
itemList.push(newItem);
console.log(itemList);
As rmlan says this is not an array, but an object. You could add your new "item" in the following way:
itemList['3'] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" };
You can just use the index operator like so:
var itemList = {
'1': { type: "car", make: "audi", price: 500, number: 10, description: "a car" },
'2': { type: "bus", make: "renault", price: 50, number: 1, description: "a bus" }
};
itemList[3] = { type: "truck", make: "volvo", price: 5, number: 20, description: "a truck" };
console.log(itemList);