42

Сортировка массива объектов по значению строкового свойства

17

У меня есть массив объектов JavaScript:

var objs = [ 
    { first_nom: 'Laszlo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

Как я могу отсортировать их по значению поля last_nom в JavaScript?

Я знаю о методе sort(a, b), но он, похоже, работает только со строками и числами. Нужно ли мне добавлять метод toString() к моим объектам?

4 ответ(ов)

1

Чувствительность к регистру

Для сортировки массива объектов в JavaScript с учётом регистра можно использовать следующий код:

arr.sort((a, b) => a.name > b.name ? 1 : -1);

Без учёта регистра

Если вам нужно произвести сортировку без учёта регистра, используйте метод toLowerCase():

arr.sort((a, b) => a.name.toLowerCase() > b.name.toLowerCase() ? 1 : -1);

Полезная заметка

При сортировке, если строки одинаковые, условие > вернёт false, и сортировка не изменит порядок. Однако, если строки равны, возврат значения 1 или -1 всё равно приведёт к правильному результату. Также можно использовать оператор >= вместо >.


Вот пример, который иллюстрирует данный подход:

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

// Определяем функции сортировки, одна с фиксированным ключом сортировки, другая с передаваемым ключом
const sorter1 = (a, b) => a.last_nom.toLowerCase() > b.last_nom.toLowerCase() ? 1 : -1;
const sorter2 = (sortBy) => (a, b) => a[sortBy].toLowerCase() > b[sortBy].toLowerCase() ? 1 : -1;

objs.sort(sorter1);
console.log("Используя sorter1 - Фиксированное свойство сортировки last_name", objs);

objs.sort(sorter2('first_nom'));
console.log("Используя sorter2 - передан параметр sortBy='first_nom'", objs);

objs.sort(sorter2('last_nom'));
console.log("Используя sorter2 - передан параметр sortBy='last_nom'", objs);

В этом коде sorter1 сортирует объекты по свойству last_nom, а sorter2 позволяет передавать любое свойство в качестве аргумента для сортировки, делая код более гибким.

0

Вот простой и быстрый способ решения вашей задачи с использованием наследования прототипов в JavaScript:

Array.prototype.sortBy = function(p) {
  return this.slice(0).sort(function(a, b) {
    return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
  });
}

Пример использования:

objs = [{age:44, name:'vinay'}, {age:24, name:'deepak'}, {age:74, name:'suresh'}];

objs.sortBy('age');
// Возвращает
// [{"age":24,"name":"deepak"},{"age":44,"name":"vinay"},{"age":74,"name":"suresh"}]

objs.sortBy('name');
// Возвращает
// [{"age":24,"name":"deepak"},{"age":74,"name":"suresh"},{"age":44,"name":"vinay"}]

Обновление: Теперь метод не изменяет оригинальный массив.

0

Вы можете использовать

Самый простой способ: Lodash

(https://lodash.com/docs/4.17.10#orderBy)

Этот метод похож на _.sortBy, за исключением того, что он позволяет задавать порядок сортировки для итераторов. Если порядок не указан, все значения сортируются в восходящем порядке. В противном случае укажите порядок "desc" для убывающей сортировки или "asc" для восходящей сортировки соответствующих значений.

Аргументы

collection (Array|Object): Коллекция для перебора. [iteratees=[_.identity]] (Array[]|Function[]|Object[]|string[]): Итераторы для сортировки. [orders] (string[]): Порядки сортировки для итераторов.

Возвращает

(Array): Возвращает новый отсортированный массив.


var _ = require('lodash');
var homes = [
    {"h_id":"3",
     "city":"Dallas",
     "state":"TX",
     "zip":"75201",
     "price":"162500"},
    {"h_id":"4",
     "city":"Bevery Hills",
     "state":"CA",
     "zip":"90210",
     "price":"319250"},
    {"h_id":"6",
     "city":"Dallas",
     "state":"TX",
     "zip":"75000",
     "price":"556699"},
    {"h_id":"5",
     "city":"New York",
     "state":"NY",
     "zip":"00010",
     "price":"962500"}
];
    
_.orderBy(homes, ['city', 'state', 'zip'], ['asc', 'desc', 'asc']);

Таким образом, вы сможете сортировать массив объектов по нескольким ключам с разными направлениями сортировки.

0

Вместо использования пользовательской функции сравнения, вы можете создать объект с собственным методом toString(), который будет вызываться встроенной функцией сортировки. Вот как это можно сделать:

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

Person.prototype.toString = function() {
    return this.lastName + ', ' + this.firstName;
}

var persons = [ new Person('Lazslo', 'Jamf'), ...];
persons.sort();

В этом примере мы создаем конструктор Person, который получает имя и фамилию. Затем мы переопределяем метод toString() в прототипе Person, чтобы он возвращал строку в формате "фамилия, имя". После этого, когда вы вызываете метод sort() на массиве persons, встроенная функция сортировки будет использовать метод toString() для сравнения объектов Person. Это позволяет легко сортировать массив без необходимости написания пользовательской функции сравнения.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь