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

3

7

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?

Platter answered 14/2, 2012 at 4:28 Comment(2)
better to choose JSON for this.Anagram
What kind of JSON structure would be suitable to group by date?Platter
G
11

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.

Gaudette answered 14/2, 2012 at 4:45 Comment(3)
This worked fantastically. Thanks! I'll definitely need to use the indexes later on.Platter
Pure javascript version for this? We are not allowed to use this library (loadsh)Dario
Without lodash or a similar library, a solution based on reduce like naortor's is the best place to start.Gaudette
B
4

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.

Brnaby answered 4/9, 2016 at 7:47 Comment(1)
A bit late, but I think it should be if(!prev[...]) {prev[...] = [curr];} else {prev[...].push(curr)}Scrubby
Z
-1

Once you have the dates in a structure that looks like this:

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

You can just use this code to convert them to the structure you want:

var dateGroups = [];

for(var year in allDates){
   dateGroups[dateGroups.length] = allDates[year];
}
Zachery answered 14/2, 2012 at 4:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.