Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Split array of objects into new arrays based on year of object's date

I have an array of objects called objarray. Each object looks like this:

var object = {
    age: "45"
    coords: "-37.807997 144.705784"
    date: Sun Jul 28 2002 00:00:00 GMT+1000 (EST)
}

(date is a Date object)

I need to push each object into a new array based on the date. I want the end result to look like this:

var dateGroups = [[object, object, object],[object, object], [object, object, object]];

Each array within dateGroups contains objects with the same date.

Is this possible to do with arrays? Previously I generated a new object which contained all the objarray objects grouped by date (dates generated from the data):

var alldates = {
  "1991" : [object, object, object],
  "1992" : [object, object],
  //etc...
}

The above seems like a weird solution in practice though, I only need to be able to access the objects by year: i.e. dateGroups[0] = array of objects from the first year

How would I get the data into something like the dateGroups array? Is there a better way to store this type of data?

like image 832
tamarasaurus Avatar asked Feb 14 '12 04:02

tamarasaurus


2 Answers

Consider using the Underscore.js groupBy function, followed by sortBy.

groupBy will produce a structure like alldates, if you call it like so:

var alldates = _.groupBy(objarray, function(obj) {
    return obj.date.getFullYear();
});

sortBy can be used to simply sort by key, like this:

var dateGroups = _.sortBy(alldates, function(v, k) { return k; });

You can also combine the two like this:

var dateGroups = _.chain(objarray)
                  .groupBy(function(obj) { return obj.date.getFullYear(); })
                  .sortBy(function(v, k) { return k; })
                  .value();

Depending on your use case, I can see reasons for using an array of arrays, or an object map of arrays. If you're looking up on index, definitely use the later.

like image 61
tjdett Avatar answered Sep 27 '22 22:09

tjdett


An answer using reduce.

var ans = objects.reduce(function(prev,curr) {
    if (!prev[curr.date.getFullYear()]) prev[curr.date.getFullYear()] = [];
    prev[curr.date.getFullYear()] = curr;
    return prev;
},[]).reduce(function(prev,curr) {
    prev.push(curr);
    return prev;
},[]);

the first reduce is for grouping the objects by dates, and the second is for making the key of the array run from 0 to the number of different years - instead of the key being the year itself.

like image 27
naortor Avatar answered Sep 28 '22 00:09

naortor