Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 542
lscmaro Avatar asked Jul 29 '26 14:07

lscmaro


1 Answers

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.

like image 179
slezica Avatar answered Aug 01 '26 02:08

slezica



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!