У меня есть массив объектов JavaScript:
var objs = [
{ first_nom: 'Lazslo', last_nom: 'Jamf' },
{ first_nom: 'Pig', last_nom: 'Bodine' },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];
Как я могу отсортировать их по значению last_nom
в JavaScript?
Я знаю о sort(a,b)
, но это, кажется, работает только над строками и числами. Нужно ли добавлять toString()
метод к моим объектам?
javascript
arrays
sorting
Тайрон Слотроп
источник
источник
Ответы:
Достаточно просто написать собственную функцию сравнения:
Или встроенный (с Марко Демайо):
источник
return a.last_nom.localeCompare(b.last_nom)
тоже будет работатьreturn a.value - b.value;
(ASC)localeCompare
важен при использовании акцентированных символов на иностранных языках, а также более элегантен.Вы также можете создать динамическую функцию сортировки, которая сортирует объекты по значению, которое вы передаете:
Таким образом, вы можете иметь массив таких объектов:
... и это будет работать, когда вы делаете:
На самом деле это уже отвечает на вопрос. Ниже написано, что со мной связались многие, жалуясь, что он не работает с несколькими параметрами .
Несколько параметров
Вы можете использовать функцию ниже для генерации функций сортировки с несколькими параметрами сортировки.
Что позволит вам сделать что-то вроде этого:
Массив подклассов
Для тех, кому повезло, кто может использовать ES6, который позволяет расширять нативные объекты:
Это позволило бы это:
источник
dynamicSort()
в приведенном выше примере заглавные буквы будут размещаться перед строчными. Например, если у меня есть значенияAPd
,Aklin
, иAbe
- результаты в ASC - то должно бытьAbe
,Aklin
,APd
. Но на вашем примере результатыAPd
,Abe
,Aklin
. В любом случае, чтобы исправить это поведение?var result = a[property].localeCompare(b[property]);
вместоvar result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
.if( !isNaN(a[property]) ) a[property] = Number(a[property]); if( !isNaN(b[property]) ) b[property] = Number(b[property]);
В ES6 / ES2015 или новее вы можете сделать это так:
До ES6 / ES2015
источник
last_nom
использования только число в массиве:1
?objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom, undefined, {numberic: true}));
underscore.js
используйте подчеркивание, его маленький и удивительный ...
источник
var sortedObjs = _.sortBy( objs, 'first_nom' );
.objs
будет не сортировать себя в результате этого. Функция вернет отсортированный массив. Это сделало бы это более явным.var reverseSortedObjs = _.sortBy( objs, 'first_nom' ).reverse();
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"> </script>
Lodash
для тех, кто предпочитает этоvar sortedObjs = _.sortBy( objs, 'first_nom' );
или, если вы хотите, чтобы это было в другом порядке:var sortedObjs = _.orderBy( objs, ['first_nom'],['dsc'] );
Не понимаю, почему люди делают это так сложно:
Для более строгих двигателей:
Поменяйте местами оператор, чтобы отсортировать его в обратном алфавитном порядке.
источник
if(a.count == b.count) return a.name > b.name; else return a.count > b.count;
Если у вас есть повторяющиеся фамилии, вы можете отсортировать их по имени-
источник
b
должно следоватьa
за массивом. Если положительное число возвращается, значит,a
должно прийти послеb
. Если0
возвращается, значит, они считаются равными. Вы всегда можете прочитать документацию: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…1, 0, -1
прежде, чем я спросил это здесь. Я просто не нашел нужную мне информацию.Простое и быстрое решение этой проблемы с использованием наследования прототипа:
Пример / Использование
Обновление: больше не изменяет исходный массив.
источник
По состоянию на 2018 год существует гораздо более короткое и элегантное решение. Просто используйте. Array.prototype.sort () .
Пример:
источник
a.value - b.value
Используется для сравнения атрибутов объекта ( цифры в данном случае) может быть принято для различных времен данных. Например, регулярное выражение может использоваться для сравнения каждой пары соседних строк .Старый ответ, который не является правильным:
ОБНОВИТЬ
Из комментария Бошана:
Более читаемый формат:
Без вложенных троичных
Пояснение:
Number()
приведуtrue
к1
иfalse
к0
.источник
arr.sort((a, b) => a.name < b.name ? -1 : (a.name > b.name ? 1 : 0))
Вместо использования пользовательской функции сравнения вы также можете создать тип объекта с помощью пользовательского
toString()
метода (который вызывается функцией сравнения по умолчанию):источник
Lodash.js (расширенный набор Underscore.js )
Хорошо не добавлять фреймворк для каждой простой логической части, но использование хорошо протестированных утилитных фреймворков может ускорить разработку и уменьшить количество ошибок.
Lodash создает очень чистый код и продвигает более функциональный стиль программирования . Одним взглядом становится ясно, какова цель кода.
Проблема ОП может быть просто решена как:
Больше информации? Например, у нас есть следующий вложенный объект:
Теперь мы можем использовать сокращение _.property,
user.age
чтобы указать путь к свойству, которое должно соответствовать. Мы отсортируем пользовательские объекты по вложенному свойству age. Да, это позволяет сопоставлять вложенные свойства!Хотите, чтобы это было наоборот? Нет проблем. Используйте _.reverse .
Хотите совместить обе цепочки ?
Или когда вы предпочитаете поток по цепочке
источник
Ты можешь использовать
Самый простой способ: Lodash
( https://lodash.com/docs/4.17.10#orderBy )
Этот метод похож на _.sortBy, за исключением того, что он позволяет указывать порядок сортировки итерируемых для сортировки. Если заказы не указаны, все значения сортируются в порядке возрастания. В противном случае укажите порядок «desc» для убывающего или «asc» для возрастающего порядка сортировки соответствующих значений.
аргументы
collection (Array | Object): коллекция для повторения. [iteratees = [_. identity]] (Array [] | Function [] | Object [] | string []): Итерации для сортировки. [orders] (string []): порядок сортировки итераций.
Возвращает
(Массив): возвращает новый отсортированный массив.
источник
Здесь есть много хороших ответов, но я хотел бы отметить, что они могут быть расширены очень просто для достижения гораздо более сложной сортировки. Единственное, что вам нужно сделать, это использовать оператор OR для цепочки функций сравнения:
Где
fn1
,fn2
... - функции сортировки, которые возвращают [-1,0,1]. Это приводит к "сортировке по fn1", "сортировке по fn2", которая почти равна ORDER BY в SQL.Это решение основано на поведении
||
оператора, который оценивает первое вычисленное выражение, которое может быть преобразовано в true .Самая простая форма имеет только одну встроенную функцию, например:
Имея два шага с
last_nom
,first_nom
порядок сортировки будет выглядеть следующим образом :Универсальная функция сравнения может выглядеть примерно так:
Эта функция может быть расширена для поддержки числовых полей, чувствительности к регистру, произвольных типов данных и т. Д.
Вы можете использовать их в цепочке по приоритету сортировки:
Дело в том, что чистый JavaScript с функциональным подходом может пройти долгий путь без внешних библиотек или сложного кода. Это также очень эффективно, так как не нужно разбирать строки
источник
Пример использования:
Автор сценария:
источник
1, 0, -1
используются для сортировки. Даже с вашим объяснением выше, которое выглядит очень хорошо - я все еще не совсем понимаю. Я всегда думаю,-1
что при использовании свойства длины массива, то есть:arr.length = -1
означает, что элемент не найден. Я, наверное, здесь все перемешиваю, но не могли бы вы помочь мне понять, почему цифры1, 0, -1
используются для определения порядка? Спасибо.a
иb
, еслиa
он больше, чемb
1, добавьте к индексуa
и поместите его позадиb
, еслиa
он меньше, чемb
, вычтите 1 изa
и поместите его передb
. Еслиa
иb
совпадают, добавьте 0a
и оставьте его там, где он есть.Я не видел этот конкретный подход , предложенный, так вот метод сравнения лаконична мне нравится использовать , которая работает для обоих
string
иnumber
:Вот объяснение
sortBy()
:sortBy()
принимает значение,fn
которое выбирает какое значение из объекта для использования в качестве сравнения, и возвращает функцию, которая может быть передана непосредственноArray.prototype.sort()
. В этом примере мы используемo.last_nom
в качестве значения для сравнения, поэтому всякий раз, когда мы получаем два объекта черезArray.prototype.sort()
такие кака также
мы используем
сравнить их.
Помня об этом
fn = o => o.last_nom
, мы можем расширить функцию сравнения до эквивалентнойОператор логического ИЛИ
||
обладает функцией короткого замыкания, которая очень полезна здесь. Из-за того, как это работает, тело функции выше означаетВ качестве дополнительного бонуса, вот эквивалент в ECMAScript 5 без функций стрелок, который, к сожалению, более многословен:
источник
Я знаю, что этот вопрос слишком старый, но я не видел ни одной реализации, похожей на мою.
Эта версия основана на идиоме преобразования Шварца .
Вот пример, как его использовать:
источник
Сортировка (более) сложных массивов объектов
Поскольку вы, вероятно, сталкиваетесь с более сложными структурами данных, такими как этот массив, я бы расширил решение.
TL; DR
проблема
Я столкнулся с ниже и не мог изменить это. Я также не хотел временно сплющивать объект. Также я не хотел использовать подчеркивание / lodash, в основном из соображений производительности и удовольствия, чтобы реализовать это самостоятельно.
Цель
Цель состоит в том, чтобы отсортировать его в первую очередь
People.Name.name
поPeople.Name.surname
Препятствия
Теперь в базовом решении используются скобочные обозначения для вычисления свойств для динамической сортировки. Здесь, однако, мы должны были бы также динамически создавать обозначение в скобках, так как можно было бы ожидать, что некоторые сработают,
People['Name.name']
но это не так.Простое выполнение
People['Name']['name']
, с другой стороны, является статичным и позволяет вам только спуститься на n-й уровень.Решение
Основным дополнением здесь будет прогулка по дереву объектов и определение значения последнего листа, который вы должны указать, а также любого промежуточного листа.
пример
Рабочий пример на JSBin
источник
Еще один вариант:
сортирует по возрастанию по умолчанию.
источник
Простая функция, которая сортирует массив объектов по свойству
Применение:
источник
Простой способ:
Посмотрите, что
'.toLowerCase()'
необходимо для предотвращения ошибок при сравнении строк.источник
objs.sort( (a,b) => b.last_nom.toLowerCase() < a.last_nom.toLowerCase() );
дополнительные параметры desc для кода Ege Özcan
источник
Комбинируя динамическое решение Ege с идеей Vinay, вы получаете хорошее надежное решение:
Применение:
источник
Согласно вашему примеру, вам нужно отсортировать по двум полям (фамилия, имя), а не по одному. Вы можете использовать библиотеку Alasql, чтобы сделать эту сортировку одной строкой:
Попробуйте этот пример на jsFiddle .
источник
источник
Учитывая оригинальный пример:
Сортировать по нескольким полям:
Ноты
a.localeCompare(b)
является общепринятым и возвращает -1,0,1 еслиa<b
,a==b
,a>b
соответственно.||
в последней строке отдаетlast_nom
приоритет надfirst_nom
.var age_order = left.age - right.age;
return -last_nom_order || -first_nom_order || -age_order;
источник
Попробуй это,
источник
Возможно, вам придется преобразовать их в нижний регистр, чтобы избежать путаницы.
источник
источник
Используя Рамду,
нпм установить рамду
источник
Это простая проблема, не знаю, почему у людей такое сложное решение.
Простая функция сортировки (на основе алгоритма быстрой сортировки ):
Пример использования:
источник