Исходя из этого исходного вопроса , как бы я применил сортировку к нескольким полям?
Используя эту слегка адаптированную структуру, как бы я отсортировал город (по возрастанию) и затем по цене (по убыванию)?
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"}
];
Мне понравился факт, чем был дан ответ, который обеспечил общий подход. Там, где я планирую использовать этот код, мне придется сортировать даты так же, как и другие вещи. Способность «заправлять» объект казалась удобной, если не немного громоздкой.
Я пытался встроить этот ответ в хороший общий пример, но мне не очень повезло.
javascript
arrays
sorting
Майк
источник
источник
sort(["first-field", "ASC"], ["second-field", "DSC"]);
что это еще сложнее, когда я пытаюсь добавить логику «праймера» первого ответа, чтобы я мог обрабатывать даты, нечувствительность к регистру и т. Д.Ответы:
Метод многомерной сортировки, основанный на этом ответе :
Обновление : вот "оптимизированная" версия. Это делает намного больше предварительной обработки и создает функцию сравнения для каждой опции сортировки заранее. Может потребоваться больше памяти (поскольку в ней хранится функция для каждой опции сортировки, но она должна быть лучше подготовлена, так как не нужно определять правильные настройки во время сравнения. Я не выполнял профилирование).
Пример использования:
DEMO
Оригинальная функция:
DEMO
источник
для не универсального, простого решения вашей точной проблемы:
источник
if
утверждение не имеет смысла.a.localeCompare(b)
в последней строке для сравнения строк ... см. Документыif (a.city === b.city)
? То есть, если два города совпадают, сравните цены, в противном случае сравните города.Вы можете использовать цепную сортировку, беря дельту значений, пока она не достигнет значения, не равного нулю.
Или, используя es6, просто:
источник
Вот простой функциональный подход. Укажите порядок сортировки, используя массив. Предварительно минус, чтобы указать нисходящий порядок.
Изменить: в ES6 это еще короче!
источник
[10,100,11,9]
. Я что-то пропустил?Сегодня я сделал довольно универсальный многофункциональный сортировщик. Вы можете взглянуть на thenBy.js здесь: https://github.com/Teun/thenBy.js
Он позволяет использовать стандартный Array.sort, но со стилем firstBy (). ThenBy (). ThenBy (). Это намного меньше кода и сложности, чем решения, опубликованные выше.
источник
Следующая функция позволит вам отсортировать массив объектов по одному или нескольким свойствам, по возрастанию (по умолчанию) или по убыванию для каждого свойства, и позволит вам выбрать, выполнять ли сравнения с учетом регистра. По умолчанию эта функция выполняет сортировку без учета регистра.
Первым аргументом должен быть массив, содержащий объекты. Последующие аргументы должны представлять собой список строк, разделенных запятыми, которые ссылаются на различные свойства объекта для сортировки. Последний аргумент (который является необязательным) является логическим, чтобы выбрать, выполнять ли сортировку с учетом регистра - используйте
true
для сортировки с учетом регистра.Функция сортирует каждое свойство / ключ по возрастанию по умолчанию. Если вы хотите конкретный ключ сортировки в порядке убывания, то вместо того, чтобы передать массив в следующем формате:
['property_name', true]
.Вот несколько примеров использования функции с последующим объяснением (где
homes
находится массив, содержащий объекты):objSort(homes, 'city')
-> сортировка по городу (по возрастанию, без учета регистра)objSort(homes, ['city', true])
-> сортировка по городу (по убыванию, с учетом регистра)objSort(homes, 'city', true)
-> сортировка по городу, затем цена (по возрастанию, с учетом регистра )objSort(homes, 'city', 'price')
-> сортировать по городу, затем по цене (по возрастанию, с учетом регистра)objSort(homes, 'city', ['price', true])
-> сортировка по городу (по возрастанию), затем по цене (по убыванию), с учетом регистра)И без дальнейших церемоний, вот функция:
А вот некоторые примеры данных:
источник
Это полный обман, но я думаю, что он добавляет ценность к этому вопросу, потому что это в основном консервированная библиотечная функция, которую вы можете использовать «из коробки».
Если у вашего кода есть доступ
lodash
или библиотека, совместимая с lodash,underscore
то вы можете использовать_.sortBy
метод. Приведенный ниже фрагмент кода скопирован непосредственно из документации lodash .Комментируемые результаты в примерах выглядят так, как будто они возвращают массивы массивов, но это просто показывает порядок, а не фактические результаты, которые представляют собой массив объектов.
источник
Вот еще один, который, возможно, ближе к вашей идее о синтаксисе
Демо: http://jsfiddle.net/Nq4dk/2/
Изменить: просто для удовольствия, вот вариант, который просто принимает строку, как SQL, так что вы можете сделать
sortObjects(homes, "city, price desc")
источник
Проще один:
источник
Мне нравится подход SnowBurnt, но он нуждается в настройке, чтобы проверить эквивалентность по городу, а НЕ разницу.
источник
Вот общая многомерная сортировка, позволяющая менять направление и / или отображать на каждом уровне.
Написано на машинописи. Для Javascript, проверьте этот JSFiddle
Код
Примеры использования
Сортировка массива людей по фамилии, а затем по имени:
Сортировка кодов языков по их названию , а не по коду языка (см.
map
), Затем по убыванию версии (см.reverse
).источник
Динамический способ сделать это с НЕСКОЛЬКИМИ ключами:
Использование:
источник
Вот общая версия решения @ Snowburnt:
Это основано на процедуре сортировки, которую я использую. Я не тестировал этот конкретный код, поэтому он может содержать ошибки, но вы поняли идею. Идея состоит в том, чтобы отсортировать на основе первого поля, которое указывает разницу, а затем остановиться и перейти к следующей записи. Итак, если вы сортируете по трем полям, и первого поля в сравнении достаточно, чтобы определить порядок сортировки двух сортируемых записей, верните результат сортировки и перейдите к следующей записи.
Я протестировал его (на самом деле с немного более сложной логикой сортировки) на 5000 записях, и он сделал это в мгновение ока. Если вы на самом деле загружаете более 1000 записей в клиент, вам, вероятно, следует использовать сортировку и фильтрацию на стороне сервера.
Этот код не обрабатывает чувствительность к регистру, но я оставляю читателю справиться с этой тривиальной модификацией.
источник
Вот мое решение, основанное на идиоме преобразования Шварца , надеюсь, вы найдете его полезным.
Вот пример того, как его использовать:
источник
По-другому
источник
Как использовать (поставить - (минус) знак перед полем, если вы хотите отсортировать в порядке убывания определенного поля)
Используя вышеуказанную функцию, вы можете отсортировать любой массив json с несколькими полями. Нет необходимости менять функцию тела вообще
источник
Адаптация ответа @chriskelly.
Большинство ответов не учитывают, что цена не будет сортироваться должным образом, если значение будет в десяти тысячах и ниже или более миллиона. JS сортирует по алфавиту. Здесь довольно хорошо ответили: почему JavaScript не может отсортировать «5, 10, 1» и здесь Как правильно отсортировать массив целых чисел .
В конечном итоге мы должны провести некоторую оценку, если поле или узел, по которому мы сортируем, является числом. Я не говорю, что использование
parseInt()
в этом случае правильного ответа, отсортированные результаты более важны.Скрипка для тестирования
источник
price
в примере в строковом формате. Если вы хотите, чтобы он работал правильно с моим примером, используйте map, чтобы сначала преобразовать поле, которое вы хотите в числовой формат. то естьconst correctedHomes = homes.map(h => ({...h, price: +h.price}))
Вау, здесь есть несколько сложных решений. Настолько сложный, что я решил придумать что-то более простое, но также и довольно мощное. Вот;
И вот пример того, как вы его используете.
Сначала это будет отсортировано по приоритету атрибутов, а затем по значению атрибутов.
источник
Вот расширяемый способ сортировки по нескольким полям.
Ноты
a.localeCompare(b)
является общепринятым и возвращает -1,0,1 еслиa<b
,a==b
,a>b
соответственно.||
в последней строке отдаетcity
приоритет надprice
.-price_order
var date_order = new Date(left.date) - new Date(right.date);
работает как цифры , так как дата математика превращается в миллисекунды с 1970 года.return city_order || -price_order || date_order;
источник
Я думаю, что это может быть самый простой способ сделать это.
https://coderwall.com/p/ebqhca/javascript-sort-by-two-fields
Это действительно просто, и я попробовал это с 3 различными парами ключ-значение, и это прекрасно работало.
Вот простой пример, посмотрите на ссылку для более подробной информации
источник
Вот мой для вашей справки, с примером:
источник
Я искал что-то подобное и закончил с этим:
Сначала у нас есть одна или несколько функций сортировки, которые всегда возвращают 0, 1 или -1:
Вы можете создавать больше функций для каждого другого свойства, по которому вы хотите сортировать.
Тогда у меня есть функция, которая объединяет эти функции сортировки в одну:
Это может быть использовано для объединения вышеуказанных функций сортировки в удобочитаемом виде:
Когда функция сортировки возвращает 0, вызывается следующая функция сортировки для дальнейшей сортировки.
источник
Просто еще один вариант. Попробуйте использовать следующую служебную функцию:
Пример использования (в вашем случае):
Следует отметить, что эта функция может быть еще более обобщенной, чтобы можно было использовать вложенные свойства, такие как 'address.city' или 'style.size.width' и т. Д.
источник
Это рекурсивный алгоритм сортировки по нескольким полям с возможностью форматирования значений перед сравнением.
Если a и b равны, он просто пробует следующее поле, пока ни одно из них не станет доступным.
источник
источник
Здесь «AffiliateDueDate» и «Title» являются столбцами, оба отсортированы в порядке возрастания.
источник
Сортировка по двум полям даты и числовому полю:
http://jsfiddle.net/hcWgf/57/
источник
С помощью :
Показать фрагмент кода
источник
Как насчет этого простого решения:
Исходя из этого вопроса массив сортировки javascript по нескольким (числовым) полям
источник