Javascript custom sorting an array of objects by year with 'pre year'

Question

So I have an array of objects ex:

var a = {user: [
 {year:'1950',name:'Joe'},
 {year:'19XX',name:'Chris'},
 {year:'1980',name:'Bob'},
 {year:'1955',name:'Jan'}
]}

I use this data to template out simple elements holding the year and name. I also have option via a select element to sort this data and then use the sorted to template it out again in order of sort. (bob,chris,jan,joe) or year. But my issue starts with year.

I am needing to continue to use a simple plugin jsonQ (http://ignitersworld.com/lab/jsonQ.html) to edit and sort data, and need to have data for year actually be a little different than desc or asc.

1st I need to edit data at various parts, like year (19XX should become 'Pre 1950'):

//inside ajax success function
var dataObj = jsonQ(data);

dataObj.find('year').value(function (data){
   if (data == '19XX') {
       return 'pre 1953'
   } else {
       return data;
   }
});

Now I will have a final product data set that needs to be sorted.

var orderedData = dataObj.sort('year', {'order' : 'ASC'});  

But this gives me the data back as:

{
 user: [
  {year:'1950',name:'Joe'},
  {year:'1955',name:'Jan'},     
  {year:'1980',name:'Bob'},
  {year:'Pre 1950',name:'Chris'}
 ]
}

What I need is the data to be returned as:

{
 user: [
  {year:'Pre 1950',name:'Chris'},
  {year:'1950',name:'Joe'},
  {year:'1955',name:'Jan'},     
  {year:'1980',name:'Bob'}
 ]
}

Any suggestions?


Show source
| javascript   | sorting   | json   | arrays   2017-01-06 20:01 3 Answers

Answers to Javascript custom sorting an array of objects by year with 'pre year' ( 3 )

  1. 2017-01-06 20:01

    Well, you can implement your own sorting criterion, and pass it to Array.sort().

    This criterion takes the form of a function(a, b) that returns a number:

    • Negative if a should go before b in the sorted list
    • Zero if a and b are essentially equal
    • Postive if a should go after b

    This may look pretty arbitrary, but think about it this way: in the simple case of sorting numbers from lesser to greater, the function returns a - b. So, f(a, b) is a - b, and a - b < 0 means a < b.

    Back to your case. Let's implement a criterion function that sorts the years from lesser to greater, putting Pre 1950 at the top:

    function byYear(a, b) {
      if (a === "Pre 1950") return -1 // a goes before
      if (b === "Pre 1950") return 1  // b goes before
    
      return parseInt(a) - parseInt(b) // lesser goes before
    })
    

    Try it in the browser console:

    > ["1980", "1970", "Pre 1950"].sort(byYear)
    ["Pre 1950", "1970", "1980"]
    

    Given that you're sorting objects, you'll need to adapt the criterion function above to work with a.year and b.year.

  2. 2017-01-06 20:01

    You could sort the array in three steps

    • sort priority years, like 19XX
    • sort by years without priority
    • sort by name.

    var a = { user: [{ year: '1950', name: 'Joe' }, { year: '19XX', name: 'Chris' }, { year: '1980', name: 'Bob' }, { year: '1955', name: 'Jan' }] };
    
    a.user.sort(function (a, b) {
        var order = { '19XX': -1 };
        return (order[a.year] || 0) - (order[b.year] || 0) || a.year - b.year || a.name.localeCompare(b.name);
    });
    
    console.log(a);

  3. 2017-01-06 20:01

    I have just found the solution, shortly after posting, while using the plugin. (which is what I wanted, Sorry, I should have specified that more).

    My problem was in my options passed into the plugin's sort()method. not easy to find since documentation isn't 100.

    var orderedData = dataObj.sort('year', {
      'order' : 'ASC',
      logic: function(val){
         return (val == 'pre 1950') ? '1911' : val;
      }
    });
    

    What this is essentially doing is replacing 'pre 1950' with 1911, just for sorting purposes.

Leave a reply to - Javascript custom sorting an array of objects by year with 'pre year'

◀ Go back