Я не видел такого конкретного подхода, поэтому я хотел бы использовать метод сравнения, который мне нравится использовать как для string
, так и для number
:
const objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
const sortBy = fn => (a, b) => -(fn(a) < fn(b)) || +(fn(a) > fn(b))
const getLastName = o => o.last_nom
const sortByLastName = sortBy(getLastName)
objs.sort(sortByLastName)
console.log(objs.map(getLastName))
Вот объяснение sortBy()
:
sortBy()
принимает параметр fn
, который выбирает какое значение для объекта для использования в качестве сравнения и возвращает функцию, которая может передаются непосредственно на Array.prototype.sort()
. В этом примере мы используем o.last_nom
как значение для сравнения, поэтому всякий раз, когда мы получаем два объекта через Array.prototype.sort()
, такие как
{ first_nom: 'Lazslo', last_nom: 'Jamf' }
и
{ first_nom: 'Pig', last_nom: 'Bodine' }
мы используем
(a, b) => -(fn(a) < fn(b)) || +(fn(a) > fn(b))
для их сравнения.
Вспоминая, что fn = o => o.last_nom
, мы можем развернуть функцию сравнения с эквивалентом
(a, b) => -(a.last_nom < b.last_nom) || +(a.last_nom > b.last_nom)
. Логическое Оператор OR ||
имеет функцию короткого замыкания, которая здесь очень полезна. Из-за того, как это работает, тело функции выше означает
if (a.last_nom < b.last_nom) return -1
return +(a.last_nom > b.last_nom)
Итак, если a < b
мы возвращаем -1
, в противном случае, если a > b
, то мы возвращаем +1
, но если a == b
, тогда a < b
и a > b
являются ложными, поэтому он возвращает +0
.
В качестве дополнительного бонуса здесь эквивалент в ECMAScript 5.1 без функций стрелок, что, к сожалению, не совсем так:
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
var sortBy = function (fn) {
return function (a, b) {
return -(fn(a) < fn(b)) || +(fn(a) > fn(b))
}
}
var getLastName = function (o) { return o.last_nom }
var sortByLastName = sortBy(getLastName)
objs.sort(sortByLastName)
console.log(objs.map(getLastName))