Aaron Case
Aaron Case

Reputation: 95

How to sort JSON into an array based on a child property

I've got an RESTful call that's returning data that resembles the following:

[{
  name: "one",
  dayID: "Tuesday},
 {
   name: "two",
   dayID: "Monday"
 },
 {
   name: 'three'
   dayID: "Tuesday
 }]

What I'm trying to do is iterate over the data and create a new array that has a nested structure based on a unique attribute. So if the array already has a Monday, push the json to that object. If not, make a new one. In this case nesting all objects under the day, so the new array would look like this:

[{"Monday":["two"]}, {"Tuesday":["one", "three"]}] 

These won't be strings in practice, they'll be additional objects but for the sake of simplicity I'm asking for strings in my example. Any help is appreciated.

Upvotes: 0

Views: 309

Answers (3)

Anurag Singh Bisht
Anurag Singh Bisht

Reputation: 2753

You can make use of Array.reduce to update your array into the desired format.

You just need to keep updating the accumulating array acc as per the condition.

var data = [{
  name: "one",
  dayID: "Tuesday"},
 {
   name: "two",
   dayID: "Monday"
 },
 {
   name: 'three',
   dayID: "Tuesday"
 }];
 
 data = data.reduce((acc, cur) => {
  if(acc.some(a => a[cur.dayID])) {
    acc.forEach(a => {
       if(a[cur.dayID]) {
         a[cur.dayID].push(cur.name)
       }
    });
  } else {
    var obj = {};
    obj[cur.dayID] = [cur.name];
    acc.push(obj);
  }
  return acc;
 }, []);
 
 console.log(data);

Upvotes: 1

Ori Drori
Ori Drori

Reputation: 192287

Use Array#reduce with a helper object:

var arr = [{
    name: "one",
    dayID: "Tuesday"
  },
  {
    name: "two",
    dayID: "Monday"
  },
  {
    name: 'three',
    dayID: "Tuesday"
  }
];


var helperObj = {};
var result = arr.reduce(function(r, o) {
  if(!helperObj[o.dayID]) {
    helperObj[o.dayID] = [];
    r.push({ [o.dayID]: helperObj[o.dayID] });
  }
  
  helperObj[o.dayID].push(o.name);

  return r;
}, []);

console.log(result);

Upvotes: 1

Nenad Vracar
Nenad Vracar

Reputation: 122077

Instead of array you could just return object since keys will be unique.

var data = [{
  name: "one",
  dayID: "Tuesday"
}, {
  name: "two",
  dayID: "Monday"
}, {
  name: 'three',
  dayID: "Tuesday"
}]

var result = data.reduce(function(r, e) {
  if (!r[e.dayID]) r[e.dayID] = [e.name];
  else r[e.dayID].push(e.name);
  return r;
}, {})

console.log(result)

Upvotes: 4

Related Questions