I have the below Javascript object.
{
1: {
trade_date: "2022-12-09T00:00:00",
settlement_date: null,
trade_type: "Buy",
quantity: 25,
security_id: "AAPL",
price: 125,
portfolio_name: " Goldman Sachs.",
counter_party: null,
trader: "trader1"
},
2: {
trade_date: "2022-12-09T00:00:00",
settlement_date: null,
trade_type: "Buy",
quantity: 25,
security_id: "AMZN",
price: 105,
portfolio_name: "JPM",
counter_party: null,
trader: "trader2"
}
}
I want this to convert to as below.
Basically, 1 is trade_id. So, I want to give that name and make it as a list.
[
{
trade_id: 1,
trade_date: '12/9/2022',
settlement_date: '1/1/0001',
trade_type: 'Buy',
quantity: '25',
security_id: 'AAPL',
price: '125',
portfolio_name: 'Goldman Sachs',
counter_party: null,
trader: 'trader1',
},
{
trade_id: 2,
trade_date: '12/9/2022',
settlement_date: '1/1/0001',
trade_type: 'Buy',
quantity: '25',
security_id: 'AMZN',
price: '125',
portfolio_name: 'JPM',
counter_party: null,
trader: 'trader2',
},
];
You can map over Object.entries.
let obj={1:{trade_date:"2022-12-09T00:00:00",settlement_date:null,trade_type:"Buy",quantity:25,security_id:"AAPL",price:125,portfolio_name:" Goldman Sachs.",counter_party:null,trader:"trader1"},2:{trade_date:"2022-12-09T00:00:00",settlement_date:null,trade_type:"Buy",quantity:25,security_id:"AMZN",price:105,portfolio_name:"JPM",counter_party:null,trader:"trader2"}};
let res = Object.entries(obj).map(([id, v]) => ({trade_id: +id, ...v}));
console.log(res);
This is probably a good use case for Array.reduce - Iterate over the keys in the object, which allows you access each sequential list element, modify its properties, and add them to a new array.
const data = {
1: {
trade_date: "2022-12-09T00:00:00",
settlement_date: null,
trade_type: "Buy",
quantity: 25,
security_id: "AAPL",
price: 125,
portfolio_name: " Goldman Sachs.",
counter_party: null,
trader: "trader1"
},
2: {
trade_date: "2022-12-09T00:00:00",
settlement_date: null,
trade_type: "Buy",
quantity: 25,
security_id: "AMZN",
price: 105,
portfolio_name: "JPM",
counter_party: null,
trader: "trader2"
}
}
const reducedData = Object.keys(data).reduce((aggregate, key) => {
const currentElement = data[key];
currentElement["trade_id"] = parseInt(key);
aggregate.push(currentElement);
return aggregate;
}, []);
console.log(reducedData);
You can use a traditional for in loop to handle this scenario.
Loop over the object using for in
Append the index as trade_id in the object
Push the final object into an empty array
let obj = {
1: {
trade_date: "2022-12-09T00:00:00",
settlement_date: null,
trade_type: "Buy",
quantity: 25,
security_id: "AAPL",
price: 125,
portfolio_name: " Goldman Sachs.",
counter_party: null,
trader: "trader1"
},
2: {
trade_date: "2022-12-09T00:00:00",
settlement_date: null,
trade_type: "Buy",
quantity: 25,
security_id: "AMZN",
price: 105,
portfolio_name: "JPM",
counter_party: null,
trader: "trader2"
}
}
let result = []
for (const i in obj) {
// Double Bitwise NOT Operator to convert string to number
obj[i].trade_id = ~~i;
result.push(obj[i]);
}
Related
I have a datalayer purchase object with two products (but user can buy more products):
This is an array I have:
[
{
name: "Product1",
id: 5986,
price: 980,
brand: "brand1",
category: "Cable & Adapter",
quantity: 1,
dimension51: "",
dimension52: "In Stock",
metric11: 980,
variant: 5771
},
{
name: "Prooduct2",
id: 5987,
price: 980,
brand: "brand2",
category: "Cable & Adapter",
quantity: 1,
dimension51: "",
dimension52: "In Stock",
metric11: 980,
variant: 5770
}
]
I want to create a JS function that would concatenate from each product ProductID and VariantID and it will return a list of productid_variantid.
I would like to via js the following:
5986_5771, 5987_5770
I have already this JS but it is returning undefined in Google Tag Manager.
function f(){
var p = {{dataLayer.ecommerce.purchase.products}};
var result = [];
for(var i=0;i<p.length;i++){
result.push(p[i].id.concat('_',p[i].variant));
}
return result.join(',');
}
Function f can be replaced with the following:
ES6:
function f(){
var p = {{dataLayer.ecommerce.purchase.products}};
return p.map(({id, variant}) => `${id}_${variant}`).join(',');
}
ES5:
function f(){
var p = {{dataLayer.ecommerce.purchase.products}};
const results = [];
for (let i = 0; i < p.length; i++) {
const product = p[i];
const resultString = p[i].id + '_' + p[i].variant;
results.push(resultString);
}
return results.join(',');
}
(The {{dataLayer.ecommerce.purchase.products}} syntax in your example is not valid in JavaScript, however I trust that this line works for you)
You can simply achieve that by a single line of code by using Array.map() method.
Try this :
const products = [
{
name: "Product1",
id: 5986,
price: 980,
brand: "brand1",
category: "Cable & Adapter",
quantity: 1,
dimension51: "",
dimension52: "In Stock",
metric11: 980,
variant: 5771
},
{
name: "Prooduct2",
id: 5987,
price: 980,
brand: "brand2",
category: "Cable & Adapter",
quantity: 1,
dimension51: "",
dimension52: "In Stock",
metric11: 980,
variant: 5770
}
];
const res = products.map((obj) => `${obj.id}_${obj.variant}`);
console.log(res.join(', '));
Updated as per the author comment (With normal forEach loop) :
const products = [
{
name: "Product1",
id: 5986,
price: 980,
brand: "brand1",
category: "Cable & Adapter",
quantity: 1,
dimension51: "",
dimension52: "In Stock",
metric11: 980,
variant: 5771
},
{
name: "Prooduct2",
id: 5987,
price: 980,
brand: "brand2",
category: "Cable & Adapter",
quantity: 1,
dimension51: "",
dimension52: "In Stock",
metric11: 980,
variant: 5770
}
];
const res = [];
products.forEach(function(obj) {
res.push(`${obj.id}_${obj.variant}`);
});
console.log(res.join(', '));
I'm a beginner at webdev and I'm having a little problem with reactjs. I have an array of data about universities, like:
const data = [
{
name: "UFSM",
total: 17,
filled: 12,
approved: 10,
reproved: 1,
dropouts: 1,
requests: 170,
approved_requests: 120,
disciplines: [{name: "engineering", value: 10}, {name:"biology", value: 20}, ...]
},
{...
disciplines: [{name: "engineering", value: 7}, ....]
},...]
I'm using the map function to map all their names into an array, like:
let data_name = props.data.map((data) => data.name);
Is it possible to use map to group into an array the value of disciplines with the same name from different universities? Having an output like:
data_engineering = ["10", "7", ...]
So that I could have all engineering related disciplines from different universities on the same array.
const data = [{
name: "UFSM",
total: 17,
filled: 12,
approved: 10,
reproved: 1,
dropouts: 1,
requests: 170,
approved_requests: 120,
disciplines: [{
name: "engineering",
value: 10
}, {
name: "biology",
value: 20
}]
}, {
name: "ABCD",
total: 17,
filled: 12,
approved: 10,
reproved: 1,
dropouts: 1,
requests: 170,
approved_requests: 120,
disciplines: [{
name: "engineering",
value: 4
}, {
name: "biology",
value: 5
}]
}, {
name: "EFGH",
total: 17,
filled: 12,
approved: 10,
reproved: 1,
dropouts: 1,
requests: 170,
approved_requests: 120,
disciplines: [{
name: "engineering",
value: 5
}, {
name: "biology",
value: 9
}]
}]
let result = {};
data.map((data) => data.disciplines).forEach((item, index) => {
item.forEach((item, index) => {
if (!result[item.name]) {
result[item.name] = []
}
result[item.name].push(item.value);
});
});
console.log(JSON.stringify(result));
If you want an array for a single discipline like engineering, you can do the following map:
data_engineering =
props.data.map((uni) => uni.disciplines.engineering);
This array will have an undefined value for a university that doesn't have an engineering value defined. But that is probably what you want, because it means the indices line up with the indices of data_name.
If you want to build such an array for all disciplines, you can do the following:
const dataDiscipline = {};
// 1. Collect all disciplines from all universities
// by making them a key of dataDiscipline.
props.data.forEach((uni) =>
uni.disciplines.forEach((discipline) =>
dataDiscipline[discipline] = null
)
);
// 2. Now build the discipline array for each discipline.
Object.keys(dataDiscipline).forEach((discipline) =>
dataDiscipline[discipline] =
props.data.map((uni) => uni.disciplines[discipline])
);
// You can now use e.g. dataDiscipline.engineering
I am running this accumulator, it works great but I find it challenging to add some proprities in the same object :
let expenseCategories = expenseObj.reduce((acc, obj) => {
let category = obj['category'];
// let amount = obj['amount'];
if (category in acc) {
acc[category] += 1;
} else {
acc[category] = 1;
}
return acc;
}, {});
{Transportation: 2, Food: 1, Clothes: 1, Bills: 2, Fun: 1, …}
My initial object also contains a transaction amount
{amount: 10, category: "Transportation", date: 20190510, expense: true, ...
{amount: 20, category: "Drinks", date: 20190510, expense: true, ...
{amount: 30, category: "Bills", date: 20190510, expense: true, ...
{amount: 40, category: "Bills", date: 20190510, expense: true, ...
My goal here is to calculate sum of each categories like bills in the example above would be 70.
I am looking to add this info to display some chart, the expected array looks something like that :
0: {name: "Transportation", value: 2, total: 123}
1: {name: "Food", value: 1, total: 456}
2: {name: "Clothes", value: 1, total: 789}
This is my attempt with the correct data I already have:
let outExpense = Object.entries(expenseCategories).map(([name, value]) => ({ name, value }));
This should be dynamic because I don't know categories prior to running code. These are user inputs. Please advise. Thanks
You are counting the occurrences of each category. You need to change your implementation a little bit. Instead of creating a number as value, you can create the object you need in the output array as value. Then, simply use Object.values() on the accumulator object to get the array of grouped values
const expenseObj = [{amount: 10, category: "Transportation", date: 20190510, expense: true},
{amount: 20, category: "Drinks", date: 20190510, expense: true},
{amount: 30, category: "Bills", date: 20190510, expense: true},
{amount: 40, category: "Bills", date: 20190510, expense: true}]
let groupCategories = expenseObj.reduce((acc, obj) => {
let { category, amount } = obj;
if (category in acc) {
acc[category].value++;
acc[category].total += amount;
} else {
acc[category] = { name: category, value: 1, total: amount };
}
return acc;
}, {});
console.log(Object.values(groupCategories))
This is how the accumulator would look like after the changes. If the current object's category already exists in the accumulator, increment the value and total. Else, add the category as key and a new object as it's value
{
"Transportation": {
"name": "Transportation",
"value": 1,
"total": 10
},
"Drinks": {
"name": "Drinks",
"value": 1,
"total": 20
},
"Bills": {
"name": "Bills",
"value": 2,
"total": 70
}
}
I have an object data as follows:
[
{
name: "Green Tea Brownie",
price: 60,
amount: 10,
seller: {
seller_id: 124,
seller_name: "Merry Shop"
}
},
{
name: "Cocoa Chiffon",
price: 20,
amount: 50,
seller: {
seller_id: 124,
seller_name: "Merry Shop"
}
},
{
name: "Milky Donut",
price: 40,
amount: 100
seller: {
seller_id: 421,
seller_name: "Sweet Bakery"
}
}
]
So I want to group data by "seller_id" and merge top level data assigns to object name "orders", just look like as following:
[
{
seller_id: 124,
seller_name: "Merry Shop",
orders: [
{
name: "Green Tea Brownie",
price: 60,
amount: 10
},
{
name: "Cocoa Chiffon",
price: 20,
amount: 50
}
]
},
{
seller_id: 421,
seller_name: "Sweet Bakery",
orders: [
{
name: "Milky Donut",
price: 40,
amount: 100
}
]
}
]
I tried to solve this problem several hours ago. Can anyone solve this case?
Thank you
You can use _.groupBy() and then _.map() the groups to requested format:
const { flow, partialRight: pr, groupBy, map, first, omit } = _
const fn = flow(
pr(groupBy, 'seller.seller_id'),
pr(map, group => ({
...first(group).seller,
orders: map(group, pr(omit, 'seller'))
}))
)
const data = [{"name":"Green Tea Brownie","price":60,"amount":10,"seller":{"seller_id":124,"seller_name":"Merry Shop"}},{"name":"Cocoa Chiffon","price":20,"amount":50,"seller":{"seller_id":124,"seller_name":"Merry Shop"}},{"name":"Milky Donut","price":40,"amount":100,"seller":{"seller_id":421,"seller_name":"Sweet Bakery"}}]
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
If you like to do with plain JS you can use reduce
const data = [{"name":"Green Tea Brownie","price":60,"amount":10,"seller":{"seller_id":124,"seller_name":"Merry Shop"}},{"name":"Cocoa Chiffon","price":20,"amount":50,"seller":{"seller_id":124,"seller_name":"Merry Shop"}},{"name":"Milky Donut","price":40,"amount":100,"seller":{"seller_id":421,"seller_name":"Sweet Bakery"}}]
const output = data.reduce((op,{name,price,amount,seller})=>{
if(op[seller['seller_id']]){
op[seller['seller_id']]['orders'].push({name,price,amount})
}
else {
op[seller['seller_id']] = {
seller_name: seller.seller_name,
seller_id: seller.seller_id,
orders: [{name,price,amount}]
}
}
return op;
},{})
console.log(Object.values(output))
Here is a pure JS solution using reduce:
const orders = [{
name: "Green Tea Brownie",
price: 60,
amount: 10,
seller: {
seller_id: 124,
seller_name: "Merry Shop"
}
}, {
name: "Cocoa Chiffon",
price: 20,
amount: 50,
seller: {
seller_id: 124,
seller_name: "Merry Shop"
}
}, {
name: "Milky Donut",
price: 40,
amount: 100,
seller: {
seller_id: 421,
seller_name: "Sweet Bakery"
}
}];
const ordersBySeller = Object.values(orders.reduce((accum, { name, price, amount, seller: { seller_id, seller_name } }) => {
const sellerOrders = accum[seller_id] ? accum[seller_id].orders || [] : [];
accum[seller_id] = { seller_id, seller_name, orders: [...sellerOrders, { name, price, amount } ] };
return accum;
}, {}));
console.log(ordersBySeller);
now I know there are a few questions that are similar like this question and this question but neither answer my question.
Okay so...
Say I have an api call and I get a response like this
[
{
amount: 23,
bill: 47,
otherData: null,
title: 'cool title'
},
{
amount: 223,
bill: 427,
otherData: null,
title: 'cooler title'
},
{
amount: 2313,
bill: 437,
otherData: null,
title: 'super cool title'
},
{
amount: 123,
bill: 147,
otherData: null,
title: 'coolest title'
}
]
is there a way I can create a new object from this array and have custom key names using a property in the object?? so the desired output is..
{
coolTitle: {
amount: 23,
bill: 47,
otherData: null,
title: 'cool title'
},
coolerTitle: {
amount: 223,
bill: 427,
otherData: null,
title: 'cooler title'
},
superCoolTitle: {
amount: 2313,
bill: 437,
otherData: null,
title: 'super cool title'
},
coolestTitle: {
amount: 123,
bill: 147,
otherData: null,
title: 'coolest title'
}
}
now I know I can convert an array of objects into an object like so..
var result = {};
for (var i=0; i<array.length; i++) {
result[array[i].key] = array[i].value;
}
but I have no Idea how I could get the title from each object, camelCase it and then create the custom key and the object
I'm not even sure if something like this is possible, any help would be appreciated
Thanks
To get the property name, extract the title and replace its space-characters with the upper-case character. Then, it's as simple as reduce-ing into an object:
const input=[{amount:23,bill:47,otherData:null,title:'cool title'},{amount:223,bill:427,otherData:null,title:'cooler title'},{amount:2313,bill:437,otherData:null,title:'super cool title'},{amount:123,bill:147,otherData:null,title:'coolest title'}]
console.log(
input.reduce((a, item) => {
const { title } = item;
const camel = title.replace(/ ./g, chars => chars[1].toUpperCase());
a[camel] = item;
return a;
}, {})
);
Use map & reduce, The reduce method will return the new object with custom key. Inside the reduce method use map. This will create an array of the value of title like ['cool','title']. Inside the same map method create a string to
convert the first character of the word to upperCase and join to join all the words
let oldArr = [{
amount: 23,
bill: 47,
otherData: null,
title: 'cool title'
},
{
amount: 223,
bill: 427,
otherData: null,
title: 'cooler title'
},
{
amount: 2313,
bill: 437,
otherData: null,
title: 'super cool title'
},
{
amount: 123,
bill: 147,
otherData: null,
title: 'coolest title'
}
]
let newArray = oldArr.reduce(function(acc, curr) {
let crtTitle = curr.title.split(' ').map(function(item, index) {
if (index !== 0) {
return item.substring(0, 1).toUpperCase() + item.substring(1, item.length);
} else {
return item;
}
}).join('');
acc[crtTitle] = curr;
return acc
}, {});
console.log(newArray)