André
André

Reputation: 318

Best way to group and sort an array of objects

I have the following demo data.

var demoData= [{"EntryGroupDate":"November 2013", 
                "DisplayName": "Hans Meier (November)", 
                "EntryGroupDateSort": 11},
               {"EntryGroupDate":"August 2013", 
                "DisplayName": "Franz Mueller (August)", 
                "EntryGroupDateSort": 8},
               {"EntryGroupDate":"November 2013", 
                "DisplayName": "Franz Huber (November)", 
                "EntryGroupDateSort": 11},
               {"EntryGroupDate":"Juli 2013", 
                "DisplayName": "Franz Schmidt (Juli)", 
                "EntryGroupDateSort": 7}
              ];

What would be the best way to group them first by EntryGroupDateSort and sort them afterwards by the same criteria. For the output I need all the information of the original array.

I have just fiddled around with UnderscoreJS but did not get the desired result by using the following code.

var myPersons = demoData;
var groups = _.groupBy(myPersons, "EntryGroupDate");
console.log(groups);
groups = _(groups).sortBy(function (item) {
    return item.EntryGroupDateSort;
});
console.log(groups);

The first console output shows the data in the format I would like to have after sorting the data.

Hopefully someone can point me in the right direction.

Upvotes: 5

Views: 20962

Answers (3)

MT0
MT0

Reputation: 167867

You can do the sort across the entire array first and then group by:

JSFIDDLE

var demoData= [{"EntryGroupDate":"November 2013", 
                "DisplayName": "Hans Meier (November)", 
                "EntryGroupDateSort": 11},
               {"EntryGroupDate":"August 2013", 
                "DisplayName": "Franz Mueller (August)", 
                "EntryGroupDateSort": 8},
               {"EntryGroupDate":"November 2013", 
                "DisplayName": "Franz Huber (November)", 
                "EntryGroupDateSort": 11},
               {"EntryGroupDate":"Juli 2013", 
                "DisplayName": "Franz Schmidt (Juli)", 
                "EntryGroupDateSort": 7}
              ];


_.sortBy( demoData, function(x){ return x.EntryGroupDateSort; } );
groups = _.groupBy( demoData, 'EntryGroupDate' );
console.log( groups );

If you want to sort after grouping then you can use (sorting on DisplayName this time):

JSFIDDLE

groups = _.groupBy( demoData, 'EntryGroupDate' );
for ( var key in groups )
    groups[key].sort( function(a,b){ var x = a.DisplayName, y = b.DisplayName; return x === y ? 0 : x < y ? -1 : 1; } );
console.log( groups );

Upvotes: 5

idbehold
idbehold

Reputation: 17168

The _.groupBy() function returns an object and you cannot "sort" an object. The keys/values of an object do not have any order. The _.sortBy() method transforms your object (containing only arrays) into an array of arrays and sorts the values based on EntryGroupDateSort. The problem is that you're trying to sort the array of arrays by the EntryGroupDateSort value (which isn't a property of an array). What you want to do is sort the grouped object of arrays by the _.first() item in each array. Here's the closest you're going to get to what you want:

var groups = _(demoData).chain()
    .groupBy("EntryGroupDate")
    .tap(function(data){ console.log(data) })
    .sortBy(function(data){
      // Note that we're sorting by EntryGroupDateSort
      // from the _.first() item in the array
      return _.first(data).EntryGroupDateSort
    })
    .tap(function(data){ console.log(data) })
    .value();

Upvotes: 1

Anand Jha
Anand Jha

Reputation: 10714

Try this,

 demoData.sort(function(a, b) {
         var textA = a.EntryGroupDateSort;
         var textB = b.EntryGroupDateSort;

         return (textA < textB) ? 1 : (textA > textB) ? -1 : 0;
         //return (textA < textB) ? -1 : (textA > textB) ? 1 : 0; //for ascending.

  });

Upvotes: 0

Related Questions