-1

I have a flat list like so:

[
{year: 2017, value: 1 },
{year: 2017, value: 2 },
{year: 2017, value: 3 },
{year: 2018, value: 1 },
{year: 2018, value: 2 },
{year: 2018, value: 3 },
{year: 2019, value: 1 },
]

etc..

I would like to restructure it like this:

[
{year: 2017, values: [1, 2, 3] },
{year: 2018, values: [1, 2, 3] },
{year: 2019, values: [1] },
]

or even

{
  "2017": [1, 2, 3],
  "2018": [1, 2, 3],
  "2019": [1]
}

I'm just trying to get an array per each year. How could I accomplish this?

rball
  • 6,925
  • 7
  • 49
  • 77

4 Answers4

1

Here is a solution :

const a = [
  {year: 2017, value: 1 },
  {year: 2017, value: 2 },
  {year: 2017, value: 3 },
  {year: 2018, value: 1 },
  {year: 2018, value: 2 },
  {year: 2018, value: 3 },
  {year: 2019, value: 1 }
]

// you can take advantage of the famous Array.reduce method.
// object solution
const b = a.reduce(function(prev,current){
  if(prev[current.year]){
    // if the key already exists, it means we should push
    prev[current.year].push(current.value)
  }else{
    // if the key does't exist, create it and add the value to an empty array
    prev[current.year] = [current.value];
  }

  return prev;

},{})
console.log(b); // { '2017': [ 1, 2, 3 ], '2018': [ 1, 2, 3 ], '2019': [ 1 ] }

// array solution(it is kind of dependant on the previous solution)
const c = []
for (key in b){
  if(b.hasOwnProperty(key)){
    c.push({year:key,value:b[key]});
  }
}
console.log(c); // [ { year: '2017', value: [ 1, 2, 3 ] }, { year: '2018', value: [ 1, 2, 3 ] }, { year: '2019', value: [ 1 ] } ]
ismnoiet
  • 4,129
  • 24
  • 30
0

The full solution then:

var aY=[
  {year: 2017, value: 1 },
  {year: 2017, value: 2 },
  {year: 2017, value: 3 },
  {year: 2018, value: 1 },
  {year: 2018, value: 2 },
  {year: 2018, value: 3 },
  {year: 2019, value: 1 }
]; // your example
var oYs= {}; // the new structure
for(var i= 0; i < aY.length; i++){
  var y= aY[i].year;
  if (oYs[y]==null){
    oYs[y]= []; // create a new array of values
  }
  oYs[y].push(aY[i].value); // append the new value
}
Koen
  • 278
  • 1
  • 7
0

If you want to return one object as result you can simply use reduce().

var data = [
{year: 2017, value: 1 },
{year: 2017, value: 2 },
{year: 2017, value: 3 },
{year: 2018, value: 1 },
{year: 2018, value: 2 },
{year: 2018, value: 3 },
{year: 2019, value: 1 },
]

var result = data.reduce(function(r, e) {
  if(!r[e.year]) r[e.year] = []
  r[e.year].push(e.value)
  return r
}, {})

console.log(result)
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
-3

This would be easier:

{
  "2017": [1, 2, 3],
  "2018": [1, 2, 3],
  "2019": [1]
}
Koen
  • 278
  • 1
  • 7