infodev
infodev

Reputation: 5235

Transform array of objects to nested array of objects

Actually I have an array of objects to transform.

[  
   { "val1":"2.0" },
   { "val2":"2.0" },
   { "val3":"2.0" },
   { "val1":"4.0" },
   { "val2":"2.0" },
   { "val3":"4.7" },
   { "val1":"4.0" },
   { "val2":"4.0" },
   { "val3":"4.0" }
]

I should take every three items and put them in a separate array with a parent item.

I would transform it to this format

[  
   [  
      "20190201",
      [  
         { "val1":"2.0" },
         { "val2":"2.0" },
         { "val3":"2.0" }
      ]
   ],
   [  
      "20190202",
      [  
         { "val2":"2.0" },
         { "val3":"2.0" },
         { "val1":"4.0" }
      ]
   ]
]

Actually here's how I made

const returnData= fileDateName.map((_fileDate: string, _index: number) => {
        return [_fileDate, [
            filteredData[_index],
            filteredData[_index + 1],
            filteredData[_index + 2],
        ]];
    });

My actual problem is that my output don't take the next three values but every time it shift one item then take the next values. I think it's because that _index value doesn't increment as it should.

Index =0 
filteredData[0],
filteredData[1],
filteredData[2],
index=1
filteredData[1],
filteredData[2],
filteredData[3],
...

but the iteration should make

Index =0 
filteredData[0],
filteredData[1],
filteredData[2],
index=3
filteredData[3],
filteredData[4],
filteredData[5],
...

Edit

FileDateName= ["20190201","20190202","20190203"]

How could it set index value every iteration ?

Upvotes: 0

Views: 76

Answers (4)

jo_va
jo_va

Reputation: 13964

You can do this with reduce by iterating over your dates array and pushing 3 items with the date to your ouptut array:

const data = [  
   { "val1":"2.0" },
   { "val2":"2.0" },
   { "val3":"2.0" },
   { "val1":"4.0" },
   { "val2":"2.0" },
   { "val3":"4.7" },
   { "val1":"4.0" },
   { "val2":"4.0" },
   { "val3":"4.0" }
];

const dates = ['20190101', '20190201', '20190301'];

const result = dates.reduce((acc, date, i) => {
  acc.push([date, [data[i * 3], data[i * 3 + 1], data[i * 3 + 2]]]);
  return acc;
}, []);

console.log(result);

Upvotes: 0

kockburn
kockburn

Reputation: 17606

You could do something like this using Array#map and Array#slice. Take the index of the dates and multiply it by 3 to find the starting position of where you should take the data.

const dates = [20190201, 20190202, 20190203]
const data=[{"val1":"2.0"},{"val2":"2.0"},{"val3":"2.0"},{"val1":"4.0"},{"val2":"2.0"},{"val3":"4.7"},{"val1":"4.0"},{"val2":"4.0"},{"val3":"4.0"}]

const res = dates.map((date, index)=>{
  const start = index * 3;
  const end = start + 3;
  return [
    date,
    data.slice(start, end)
  ]
});

console.log(res);

Upvotes: 2

Selmi Karim
Selmi Karim

Reputation: 2235

try this one:

const returnData= fileDateName.map((_fileDate: string, _index: number)
=> {
        if(_index % 3 === 0)  
          return [_fileDate, [
              filteredData[_index],
              filteredData[_index + 1],
              filteredData[_index + 2],
          ]];
    });

Upvotes: 1

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48600

This is a fairly easy task.

Just reduce the array into an array of chunks the size of three items. Along the way, use modular arithmetic to determine when you need to start a new group.

var data = [  
   { "val1": "2.0" },
   { "val2": "2.0" },
   { "val3": "2.0" },
   { "val1": "4.0" },
   { "val2": "2.0" },
   { "val3": "4.7" },
   { "val1": "4.0" },
   { "val2": "4.0" },
   { "val3": "4.0" }
];

console.log(groupData(data, 3, new Date(2019, 1, 1)));

function formatDate(d) {
  return [
    d.getFullYear(),
    ('00' + (d.getMonth() + 1)).substr(-2),
    ('00' + d.getDate()).substr(-2),
  ].join('');
}

function groupData(data, size, startDate) {
  return data.reduce((result, item, index) => {
    if (index % size === 0) {
      result.push([ formatDate(startDate), [ item ] ]); // Begin a new group
      startDate.setDate(startDate.getDate() + 1); // Increment the day by 1
    } else {
      result[result.length - 1][1].push(item); // Add item to the last group
    }
    return result;
  }, []);
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

Upvotes: 0

Related Questions