Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I sort an Array with coffeescript?

Tags:

with an Array like this:

users = [     { id: 1, fname: 'Fred', lname: 'Flinstone', state: 'CA' },     { id: 2, fname: 'George', lname: 'Winston', state: 'FL' },    { id: 3, fname: 'Luke', lname: 'Skywalker', state: 'CA' } ] 

and you want to sort by last name with coffeescript, you can do this:

users.sort (a,b) ->   return if a.lname.toUpperCase() >= b.lname.toUpperCase() then 1 else -1 

I tried using a function like this:

sortBy = (field, reverse, primer) ->     key = (x) ->       return if primer? then primer x[field] else x[field]     return (a,b) ->       A = key a       B = key b       return (A < B ? -1 : (A > B ? 1 : 0)) * [1,-1][+!!reverse] 

which was invoked like this:

users.sort sortBy "lname", false, (a) ->    return a.toUpperCase() 

but that didn't sort the array properly.

Is there a way to sort by more than 1 field, i.e. sort first by State, and then by Last Name? I was hoping to improve upon the "sortBy" function above and add ability to sort by at least 2 fields.

like image 602
jiy Avatar asked Mar 20 '12 23:03

jiy


Video Answer


1 Answers

There's a simpler way. Just re-use your generalized sorting function, and concatenate them using ||:

sortBy = (key, a, b, r) ->     r = if r then 1 else -1     return -1*r if a[key] > b[key]     return +1*r if a[key] < b[key]     return 0  users.sort (a,b) ->     sortBy('id', a, b, true) or     sortBy('lname', a, b) or     sortBy('fname', a, b) 

Functions are cheap. You can then build an abstraction for that:

sortByMultiple = (a, b, keys) ->     return r if (r = sortBy key, a, b) for key in keys     return 0  users.sort (a,b) -> sortByMultiple a, b, ['id', 'lname', 'fname'] 

But then you lose the ability to set order or other parameters on each of them.

like image 150
Ricardo Tomasi Avatar answered Nov 14 '22 12:11

Ricardo Tomasi