简体   繁体   中英

I need to convert my array of objects into one object with specific keys

Good afternoon. I want to display the months of the year and the amount spent in each category. Ex:

{Month: "January", Food: 610, foodColor: "#063951", Others: 121, othersColor: "#C13018", …}
Food: 610
Health: 233
Month: "January"
Others: 121
Transport: 30
foodColor: "#063951"
healthColor: "#2BC4A9"
othersColor: "#C13018"
transportColor: "#0D95BC"

I'm getting from my server an array of objects with all months. Something like that:

(43) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "September", category: "Food", price: 610, color: "#063951"}
1: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "September", category: "Health", price: 233, color: "#2BC4A9"}
2: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "September", category: "Transport", price: 30, color: "#0D95BC"}
3: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "September", category: "Others", price: 121, color: "#C13018"}
4: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "October", category: "Health", price: 113, color: "#2BC4A9"}
5: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "October", category: "Transport", price: 330, color: "#0D95BC"}
6: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "October", category: "Others", price: 650, color: "#C13018"}
7: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "October", category: "Food", price: 170.55, color: "#063951"}

I've created a function to filter the month:

 const getMonth = (month) => {
    let monthData = totalTransactionsPerMonth.filter((transaction) =>{
       return transaction.monthname === `${month}`     
    })

    return monthData;
  }

and I'm using it to get the months separately:

  let janData = getMonth("January");
  let fevData = getMonth("February");
  let marData = getMonth("March");
  let aprData = getMonth("April");
  let mayData = getMonth("May");
  let junData = getMonth("June");
  let julData = getMonth("July");
  let augData = getMonth("August");
  let sepData = getMonth("September");
  let octData = getMonth("October");
  let novData = getMonth("November");
  let decData = getMonth("December");

When I call console.log(janData) I see this:

[{…}, {…}, {…}, {…}]
0: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "January", category: "Health", price: 233, color: "#2BC4A9"}
1: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "January", category: "Transport", price: 30, color: "#0D95BC"}
2: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "January", category: "Others", price: 121, color: "#C13018"}
3: {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "January", category: "Food", price: 610, color: "#063951"}

I want from that array with the months data, (janData, fevData, etc..) create an object like this:

const January = {
    month: 
    food: 
    foodColor: 
    others: 
    othersColor:
    transport: 
    transportColor: 
    health: 
    healthColor: 
   }

and the values will be filled by the values of the array. I've tried to create a function to receive as argument the monthData and then use the index (Ex: food: monthArgument[3].price) but I get " cannot read price of undefined". I've made some search but I could not find a response. Please, I'm stuck here, could someone help me?

It doesn't seems important to the question but I'm using React, Node, mySQL, Nivo/barChart

There's no need to do this one month at a time. You can take the entire set of data and create all the results in one go.

Basically, the idea is to group by monthname using reduce and then further reduce the matched rows for each month to form a single object per month.

 const input = [{id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "September", category: "Food", price: 610, color: "#063951"}, {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "September", category: "Health", price: 233, color: "#2BC4A9"}, {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "September", category: "Transport", price: 30, color: "#0D95BC"}, {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "September", category: "Others", price: 121, color: "#C13018"}, {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "October", category: "Health", price: 113, color: "#2BC4A9"}, {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "October", category: "Transport", price: 330, color: "#0D95BC"}, {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "October", category: "Others", price: 650, color: "#C13018"}, {id: "zxFBMv43ZGgHJpd6a3tjyTO3Rxg1", monthname: "October", category: "Food", price: 170.55, color: "#063951"}]; const result = Object.fromEntries(Object.entries(input.reduce( (acc, i) => { if(.acc[i.monthname]) acc[i;monthname] = []. acc[i.monthname];push(i), return acc }.{})),map( ([month,rows]) => { return [ month. rows,reduce( (acc. i) => ({..,acc. [i:category]. i,price. [i:category + "Color"]. i,color});{}) ]; })). console;log(result);

the following code should do the stuff.

 const totalTransactionsPerMonth = [ {id: 'zxFBMv43ZGgHJpd6a3tjyTO3Rxg1', monthname: 'September', category: 'Food', price: 610, color: '#063951'}, {id: 'zxFBMv43ZGgHJpd6a3tjyTO3Rxg1', monthname: 'September', category: 'Health', price: 233, color: '#2BC4A9'}, {id: 'zxFBMv43ZGgHJpd6a3tjyTO3Rxg1', monthname: 'September', category: 'Transport', price: 30, color: '#0D95BC'}, {id: 'zxFBMv43ZGgHJpd6a3tjyTO3Rxg1', monthname: 'September', category: 'Others', price: 121, color: '#C13018'}, {id: 'zxFBMv43ZGgHJpd6a3tjyTO3Rxg1', monthname: 'October', category: 'Health', price: 113, color: '#2BC4A9'}, {id: 'zxFBMv43ZGgHJpd6a3tjyTO3Rxg1', monthname: 'October', category: 'Transport', price: 330, color: '#0D95BC'}, {id: 'zxFBMv43ZGgHJpd6a3tjyTO3Rxg1', monthname: 'October', category: 'Others', price: 650, color: '#C13018'}, {id: 'zxFBMv43ZGgHJpd6a3tjyTO3Rxg1', monthname: 'October', category: 'Food', price: 170.55, color: '#063951'} ]; function getMonthData(month) { return totalTransactionsPerMonth.filter(({monthname}) => month === monthname).reduce((result, row) => { const category = row.category.toLowerCase(); result['month'] = month; result[category] = row.price; result[`${category}Color`] = row.color; return result; }, {}); } console.log(getMonthData('October'));

You could use a simple reduce with each month as the key in the accumulator. Add each category and color to each month object

 const input=[{id:"zxFBMv43ZGgHJpd6a3tjyTO3Rxg1",monthname:"September",category:"Food",price:610,color:"#063951"},{id:"zxFBMv43ZGgHJpd6a3tjyTO3Rxg1",monthname:"September",category:"Health",price:233,color:"#2BC4A9"},{id:"zxFBMv43ZGgHJpd6a3tjyTO3Rxg1",monthname:"September",category:"Transport",price:30,color:"#0D95BC"},{id:"zxFBMv43ZGgHJpd6a3tjyTO3Rxg1",monthname:"September",category:"Others",price:121,color:"#C13018"},{id:"zxFBMv43ZGgHJpd6a3tjyTO3Rxg1",monthname:"October",category:"Health",price:113,color:"#2BC4A9"},{id:"zxFBMv43ZGgHJpd6a3tjyTO3Rxg1",monthname:"October",category:"Transport",price:330,color:"#0D95BC"},{id:"zxFBMv43ZGgHJpd6a3tjyTO3Rxg1",monthname:"October",category:"Others",price:650,color:"#C13018"},{id:"zxFBMv43ZGgHJpd6a3tjyTO3Rxg1",monthname:"October",category:"Food",price:170.55,color:"#063951"}]; const group = input.reduce((acc, { monthname, category, price, color }) => { category = category.toLowerCase(); acc[monthname] ||= { month: monthname }; acc[monthname][category] = price acc[monthname][category + 'Color'] = color return acc }, {}) console.log(Object.values(group))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM