Skip to content

Instantly share code, notes, and snippets.

@nathansmith
Last active September 15, 2021 14:22
Show Gist options
  • Save nathansmith/5811250 to your computer and use it in GitHub Desktop.
Save nathansmith/5811250 to your computer and use it in GitHub Desktop.
Function to sort an array of objects by a particular key's value.
function sort_by_key_value(arr, key) {
var to_s = Object.prototype.toString;
var valid_arr = to_s.call(arr) === '[object Array]';
var valid_key = typeof key === 'string';
if (!valid_arr || !valid_key) {
return;
}
arr = arr.slice();
return arr.sort(function(a, b) {
var a_key = String(a[key]);
var b_key = String(b[key]);
var n = a_key - b_key;
return !isNaN(n) ? n : a_key.localeCompare(b_key);
});
}
/*
Used like this...
*/
var old_arr = [
{
test: 'betty'
},
{
test: 2
},
{
test: 'alfred'
},
{
test: 'Chris'
},
{
test: 1
},
{
test: 'Betty'
},
{
test: 3
},
{
test: 'Alfred'
},
{
test: 'chris'
}
];
var new_arr = sort_by_key_value(old_arr, 'test');
new_arr.forEach(function(item) {
console.log(item.test);
});
/*
Returns...
[
{
test: 1
},
{
test: 2
},
{
test: 3
},
{
test: 'alfred'
},
{
test: 'Alfred'
},
{
test: 'betty'
},
{
test: 'Betty'
},
{
test: 'chris'
},
{
test: 'Chris'
}
]
*/
@nathansmith
Copy link
Author

For what it's worth, here are examples of how Underscore (and Lo-Dash) handle this particular test array:

Passing in numbers/strings (no resulting sort, same as input)…

http://cl.ly/image/001B1H1Y0W2j

Passing in all strings (sorted, but not kept alphabetical)…

http://cl.ly/image/2W050F3s2X0k

I'm just pointing that out since a few people have asked "Doesn't Underscore (or Lo-Dash) do that?"

Answer:

No, they don't. However, I wouldn't expect them to.

This is for sorting data to be displayed in an HTML <table>, which is by its nature sort of a kludge anyway.

@nathansmith
Copy link
Author

UPDATE

Courtesy of a coworker, you could do this in Underscore (or Lo-Dash) by passing a custom iterator function.

function sort_by_key_value(arr, key) {
  return _.sortBy(arr, function(item) {
    return String(item[key]).toLowerCase();
  });
}

var new_arr = sort_by_key_value(old_arr, 'test');

new_arr.forEach(function(item) { 
  console.log(item.test);
});

That gets 99% there, except that lowercase variations of words don't necessarily precede their uppercase counterparts…

http://cl.ly/image/272e2h0R0512

Note:

"alfred" precedes "Alfred" and "betty" precedes "Betty", yet "Chris" precedes "chris".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment