简体   繁体   中英

re-organize json data with vanilla javascript

I am consuming data from a web service that sends JSON data with the following structure. You can see my at https://es6console.com/jkadxuk1/ .

Problems: my current attempt is very slow. And it works only if all dates have the same number of reporting times. For eg in the records below, there are two times files for 2018-08-01 and one for 2018-07-31 but the 31st still shows two records when re-organized. Hope I am making sense.

function dbDateTimeToDateTme(value){
   /*
  value isforamtted as 2018-08-04T22:00:00Z
   Here, we split them

   @output: an array of date and time. Note we don't validate
   */
  reply=[];
   if(value){
      date=value.substring(0,10)
      time=value.substring(11,19)
      reply.push(date,time);

   }
   return reply;
}

   function viewFullTablar(acquired_data){


     total=acquired_data.length;
    if(total==0){
      return false;
    }
    data=[]; //reorganized data
    location_name="";
    location_code=0;
    datetime=[];
    for(var i=0;i<total;i++){
       date_index=-1;
       place_index=-1; //
      location_name=acquired_data[i]['store']
      location_code=acquired_data[i]['location_id']
      datetime=dbDateTimeToDateTme(acquired_data[i]['for_date']); //0=date,1=time
      //now check if we have already added the location by its location_code

      for(var counter=0;counter<data.length;counter++){

        if (data[counter]['location_id']==location_code){

          place_index=counter;
          break;
        }
      }

      //do we add the place?
      if(place_index==-1){
        //yes add it
        data.push(
            {
              'index':i,
              'store':location_name,
              'location_id':location_code,
              'dates':[]
            }
          );
        place_index=0; //first element now
      }

      //does the date exist yet or not?
       date_blocks=data[place_index]['dates'];

      for(counter=0;counter<date_blocks.length;counter++){
        if (date_blocks[counter]['date']==datetime[0]){

          date_index=counter;
          break;
        }
      }

      //add the date to the place or not?
      if(date_index==-1){
           data[place_index]['dates'].push(
            {
              'date':datetime[0],
              'main':[]
            }
          );
           date_index=0;
      }

      //now add time and weather details

        data[place_index]['dates'][date_index]['main'].push(

            {
              'time':datetime[1],
              'income':acquired_data[i]['income']
            }

          );








    }

   return data;

   }

var data={

        "data": [
            {
                "expense": "1026.2100",
                "income": "869.4500",
                "location_id": 1,
                "for_date": "2018-07-31T04:00:00Z",
                "store": "Eastern Province"

            },
            {
                "expense": "1026.3300",
                "income": "869.0300",
                "location_id": 1,
                "for_date": "2018-08-01T00:00:00Z",
                "store": "Eastern Province"
            },
            {
                "expense": "1026.7600",
                "income": "870.2000",
                "location_id": 1,
                "for_date": "2018-08-01T04:00:00Z",
                "store": "Eastern Province",

            },

        ]
    }

console.log(viewFullTablar(data['data']));

Each day can have a maximum 8 different hours of reporting but the minimum can be as low as 1 or 0 even (if nothing has been filed yet).

For display purposes, I want to get the following array out of if:

[{

store:"Eastern Province",
location_id:1,
dates:[
   {
    'date':'2018-07-31',
     main:[
        {'time':04:00:00,
         'income':1026
         }];

     }];

 }];

or:

East Province
   2018-07-31
      04:00:00 value value
      09:00:00 value value
   2018-08-01
      09:00:00  value value
      10:00:10  value value

I have added https://es6console.com/jkadxuk1/ here.

You can use reduce to greatly improve readability. Use .find() to look back through the array to find objects that already exist, and update them accordingly:

 const data = { "data": [ { "expense": "1026.2100", "income": "869.4500", "location_id": 1, "for_date": "2018-07-31T04:00:00Z", "store": "Eastern Province" }, { "expense": "1026.3300", "income": "869.0300", "location_id": 1, "for_date": "2018-08-01T00:00:00Z", "store": "Eastern Province" }, { "expense": "1026.7600", "income": "870.2000", "location_id": 1, "for_date": "2018-08-01T04:00:00Z", "store": "Eastern Province", }, ] }; const res = data.data.reduce((obj, item) => { // Do we already have this location in the final array? const foundItem = obj.find((i) => i.location_id == item.location_id); const date = item.for_date.substr(0,10); const time = item.for_date.substr(11,8); // Let's just append the date if (foundItem) { // Search for the current date const foundDate = foundItem.dates.find((i) => i.date == date); // Is there already a date in the array? if (foundDate) { // Push the time into the array foundDate.main.push({ time, expense: item.expense, income: item.income }); } else { // Push a new date object, with this time foundItem.dates.push({ date, main: [{ time, expense: item.expense, income: item.income }] }); } } else { // Push a whole new location obj.push({ store: item.store, location_id: item.location_id, dates: [ { date, main: [{ time, expense: item.expense, income: item.income }] } ] }); } return obj; }, []); console.log(res); 

You can use reduce using id and date as key value if you don't want to do a lot of iterations, after that you can use map or other function to unwind result

 const data = [ { "expense": "1026.2100", "income": "869.4500", "location_id": 1, "for_date": "2018-07-31T04:00:00Z", "store": "Eastern Province" }, { "expense": "1026.3300", "income": "869.0300", "location_id": 1, "for_date": "2018-08-01T00:00:00Z", "store": "Eastern Province" }, { "expense": "1026.7600", "income": "870.2000", "location_id": 1, "for_date": "2018-08-01T04:00:00Z", "store": "Eastern Province", }, ]; const result = data.reduce((acum = {}, current) => { const year = current.for_date.slice(0, 10); const hour = current.for_date.slice(11, 19); if (!acum[current.location_id]) { acum[current.location_id] = { store: current.store, location_id: current.location_id, dates: { [current.for_date]: { date: current.for_date, main: [ { time: '', income: current.income, expense: current.expense, }, ], } } } } else if (!acum[current.location_id].dates[year]) { acum[current.location_id].dates[year] = { date: year, main: [ { time: '', income: current.income, expense: current.expense, }, ], } } else { acum[current.location_id].dates[year].main.push({ time: '', income: current.income, expense: current.expense, }); } return acum; }, {}); console.log(result); console.log('---------') let arr = Object.keys(result).map(key => { let res = result[key] res.dates = Object.keys(result[key].dates).map(date => result[key].dates[date]) return res; }); console.log(arr) 

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