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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With