Как отсортировать массив объектов по значениям свойств в JavaScript?
У меня есть следующий массив объектов:
var homes = [
{
"h_id": "3",
"city": "Dallas",
"state": "TX",
"zip": "75201",
"price": "162500"
}, {
"h_id": "4",
"city": "Beverly Hills",
"state": "CA",
"zip": "90210",
"price": "319250"
}, {
"h_id": "5",
"city": "New York",
"state": "NY",
"zip": "00010",
"price": "962500"
}
];
Как создать функцию для сортировки этих объектов по свойству price как в порядке возрастания, так и в порядке убывания, используя только JavaScript?
Содержание
- Базовая сортировка с помощью метода sort()
- Сортировка по числовым значениям свойств
- Создание переиспользуемой функции сортировки
- Работа с различными типами данных
- Избегание изменения исходного массива
- Продвинутые техники сортировки
- Практические примеры
Базовая сортировка с помощью метода sort()
Метод JavaScript sort() является основным инструментом для сортировки массивов. По умолчанию он сортирует элементы как строки в порядке возрастания, но для сортировки объектов по их свойствам необходимо предоставить пользовательскую функцию сравнения.
var homes = [
{
"h_id": "3",
"city": "Dallas",
"state": "TX",
"zip": "75201",
"price": "162500"
}, {
"h_id": "4",
"city": "Beverly Hills",
"state": "CA",
"zip": "90210",
"price": "319250"
}, {
"h_id": "5",
"city": "New York",
"state": "NY",
"zip": "00010",
"price": "962500"
}
];
Функция сравнения принимает два параметра (обычно a и b), представляющих два элемента из массива, и должна возвращать:
- Отрицательное значение, если
aдолжен идти передb - Положительное значение, если
bдолжен идти передa - Ноль, если порядок должен остаться без изменений
Сортировка по числовым значениям свойств
Для числовых свойств, таких как price, можно использовать простую арифметику для определения порядка сортировки. Этот подход хорошо работает с числами и числовыми строками.
Порядок возрастания (от меньшего к большему)
homes.sort((a, b) => a.price - b.price);
Порядок убывания (от большего к меньшему)
homes.sort((a, b) => b.price - a.price);
Важно: Поскольку значения
priceв вашем примере являются строками, их следует преобразовать в числа для правильной сортировки:
homes.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
Создание переиспользуемой функции сортировки
Для лучшей организации кода и его повторного использования можно создать универсальную функцию сортировки, которая может обрабатывать различные свойства и порядки сортировки.
function sortByProperty(array, property, order = 'asc') {
return array.sort((a, b) => {
const valueA = parseFloat(a[property]);
const valueB = parseFloat(b[property]);
if (order === 'asc') {
return valueA - valueB;
} else {
return valueB - valueA;
}
});
}
// Примеры использования:
sortByProperty(homes, 'price', 'asc'); // По возрастанию
sortByProperty(homes, 'price', 'desc'); // По убыванию
Как объясняется на SitePoint, эта функция имеет два параметра — ключ, по которому мы хотим сортировать, и порядок результатов (по возрастанию или по убыванию).
Работа с различными типами данных
Разные типы свойств требуют разных подходов к сравнению:
Числовые свойства
// По возрастанию
array.sort((a, b) => a.price - b.price);
// По убыванию
array.sort((a, b) => b.price - a.price);
Строковые свойства
// По возрастанию (А-Я)
array.sort((a, b) => a.name.localeCompare(b.name));
// По убыванию (Я-А)
array.sort((a, b) => b.name.localeCompare(a.name));
Свойства с датами
// По возрастанию (от старых к новым)
array.sort((a, b) => new Date(a.date) - new Date(b.date));
// По убыванию (от новых к старым)
array.sort((a, b) => new Date(b.date) - new Date(a.date));
Избегание изменения исходного массива
Метод sort() сортирует массивы на месте, что означает, что он изменяет исходный массив. Чтобы сохранить исходный массив, сначала создайте его копию:
// Использование оператора spread (ES6+)
const sortedHomes = [...homes].sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
// Использование slice()
const sortedHomes = homes.slice().sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
// Использование Array.from()
const sortedHomes = Array.from(homes).sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
Как демонстрирует 30 seconds of code, создание копии массива с помощью оператора spread избегает изменения исходного массива.
Продвинутые техники сортировки
Сортировка по нескольким свойствам
homes.sort((a, b) => {
const priceDiff = parseFloat(a.price) - parseFloat(b.price);
if (priceDiff !== 0) return priceDiff;
return a.city.localeCompare(b.city); // Сортировка по городу, если цены равны
});
Сортировка строк без учета регистра
homes.sort((a, b) => a.city.toLowerCase().localeCompare(b.city.toLowerCase()));
Пользовательская логика сортировки
homes.sort((a, b) => {
const priceA = parseFloat(a.price);
const priceB = parseFloat(b.price);
// Сортировка по ценовому диапазону
if (priceA < 200000 && priceB >= 200000) return -1;
if (priceA >= 200000 && priceB < 200000) return 1;
return priceA - priceB;
});
Практические примеры
Вот полные примеры использования вашей конкретной структуры данных:
Пример 1: Базовая сортировка по цене
var homes = [
{
"h_id": "3",
"city": "Dallas",
"state": "TX",
"zip": "75201",
"price": "162500"
}, {
"h_id": "4",
"city": "Beverly Hills",
"state": "CA",
"zip": "90210",
"price": "319250"
}, {
"h_id": "5",
"city": "New York",
"state": "NY",
"zip": "00010",
"price": "962500"
}
];
// Сортировка по возрастанию цены
const ascendingPrice = [...homes].sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
console.log(ascendingPrice);
/*
Вывод:
[
{h_id: "3", city: "Dallas", state: "TX", zip: "75201", price: "162500"},
{h_id: "4", city: "Beverly Hills", state: "CA", zip: "90210", price: "319250"},
{h_id: "5", city: "New York", state: "NY", zip: "00010", price: "962500"}
]
*/
// Сортировка по убыванию цены
const descendingPrice = [...homes].sort((a, b) => parseFloat(b.price) - parseFloat(a.price));
console.log(descendingPrice);
/*
Вывод:
[
{h_id: "5", city: "New York", state: "NY", zip: "00010", price: "962500"},
{h_id: "4", city: "Beverly Hills", state: "CA", zip: "90210", price: "319250"},
{h_id: "3", city: "Dallas", state: "TX", zip: "75201", price: "162500"}
]
*/
Пример 2: Продвинутая функция сортировки
function sortHomes(homes, sortBy, order = 'asc') {
const sorted = [...homes]; // Создаем копию, чтобы избежать изменения исходного массива
sorted.sort((a, b) => {
let valueA, valueB;
// Обработка различных типов данных
if (typeof a[sortBy] === 'string' && !isNaN(a[sortBy])) {
// Числовая строка
valueA = parseFloat(a[sortBy]);
valueB = parseFloat(b[sortBy]);
} else if (typeof a[sortBy] === 'number') {
// Число
valueA = a[sortBy];
valueB = b[sortBy];
} else {
// Строка или другой тип
valueA = a[sortBy].toString().toLowerCase();
valueB = b[sortBy].toString().toLowerCase();
}
// Применяем порядок сортировки
if (order === 'asc') {
if (typeof valueA === 'number') {
return valueA - valueB;
}
return valueA.localeCompare(valueB);
} else {
if (typeof valueA === 'number') {
return valueB - valueA;
}
return valueB.localeCompare(valueA);
}
});
return sorted;
}
// Примеры использования:
console.log(sortHomes(homes, 'price', 'asc'));
console.log(sortHomes(homes, 'price', 'desc'));
console.log(sortHomes(homes, 'city', 'asc'));
Источники
- Array.prototype.sort() - JavaScript | MDN
- JavaScript Array Sort - W3Schools
- Sort an Array of Objects in JavaScript with the sort() method— SitePoint
- How to Sort an Array of Objects by Property Values in JavaScript
- Sort an Array of Objects in JavaScript - 30 seconds of code
- How to sort an array of objects by string property value in JavaScript · CoreUI
- JavaScript: Sort an array of objects by a numeric property in each object - Stack Overflow
Заключение
Сортировка массивов объектов по значениям свойств в JavaScript становится простой задачей, как только вы понимаете метод sort() и функции сравнения. Ключевые выводы включают:
- Используйте
a.price - b.priceдля сортировки чисел по возрастанию иb.price - a.priceдля сортировки по убыванию - Преобразуйте строковые числа в настоящие числа с помощью
parseFloat()для точной числовой сортировки - Создавайте копии массивов с помощью оператора spread (
[...array]) илиslice(), чтобы избежать изменения исходных данных - Стройте переиспользуемые функции, которые могут обрабатывать различные свойства и порядки сортировки
- Используйте
localeCompare()для сравнения строк и корректно обрабатывайте различные типы данных - Учитывайте крайние случаи, такие как отсутствующие свойства или смешанные типы данных в вашей логике сортировки
Реализуя эти техники, вы можете эффективно сортировать массивы объектов с домами по цене или любому другому свойству в порядке возрастания или убывания, сохраняя при этом чистый и поддерживаемый код.