Как отсортировать массив объектов по какому-то из ключей?
Как сделать фильтр массива объектов по условию ключа read от false к true?
array: [
{sex: "male", name: "Alex Ivanov", message: "Lorem lorem inspur", time: "11:30", date:"11.12.2020", read: false},
{sex: "female", name: "Olena", message: "Lorem lorem inspur", time: "11:10", date:"15.12.2020", read: false},
{sex: "male", name: "Kirill", message: "Lorem lorem inspur", time: "11:20", date:"11.11.2020", read: true}
]
Ответы (3 шт):
Учитывая что sort() меняет исходный массив, то нужно создать копию исходного массива, можно таким образом: [...array]
const array = [
{sex: "male", name: "Kirill", message: "Lorem lorem inspur", time: "11:20", date:"11.11.2020", read: true},
{sex: "male", name: "Alex Ivanov", message: "Lorem lorem inspur", time: "11:30", date:"11.12.2020", read: false},
{sex: "female", name: "Olena", message: "Lorem lorem inspur", time: "11:10", date:"15.12.2020", read: false}
]
const result = [...array].sort((a,b) => a.read - b.read)
console.log(result)
Для чего-то дискретного как bool не обязательно использовать sort
const input = [
{sex: "male", name: "Alex Ivanov", message: "Lorem lorem inspur", time: "11:30", date:"11.12.2020", read: false},
{sex: "male", name: "Kirill", message: "Lorem lorem inspur", time: "11:20", date:"11.11.2020", read: true},
{sex: "female", name: "Olena", message: "Lorem lorem inspur", time: "11:10", date:"15.12.2020", read: false},
{sex: "female", name: "Olena", message: "Lorem lorem inspur", time: "11:10", date:"15.12.2020", read: false},
{sex: "male", name: "Kirill", message: "Lorem lorem inspur", time: "11:20", date:"11.11.2020", read: true},
{sex: "male", name: "Kirill", message: "Lorem lorem inspur", time: "11:20", date:"11.11.2020", read: true},
{sex: "female", name: "Olena", message: "Lorem lorem inspur", time: "11:10", date:"15.12.2020", read: false},
]
const output = input.reduce((a, b) => b.read ? [[...a[0]], [...a[1], b]] : [[...a[0], b], [...a[1]]], [[], []]).flat()
console.log(output)
Обычно в базах и таблицах идет сортировка не только по одному ключу (полю) а по каждому, но у каждой сортировки свой приоритет.
В данном случае приоритет по read
Тут два примера для наглядности я упростил объекты (даты нужно сортировать особо):
только по
readпо
readидругим ключам
Еще нужно помнить что функция сортировки работает с функцией сравнения возвращающей одно из 3х значений (об этом часто забывает что приводит к неправильному использованию, разные браузеры на эту забывчивость реагируют по-своему)
function compare(a, b) {
if (a меньше b по некоторому критерию сортировки) {
return -1;
}
if (a больше b по некоторому критерию сортировки) {
return 1;
}
// a должно быть равным b
return 0;
}
const arr = [
{sex: "male", name: "B", read: false},
{sex: "female", name: "B", read: true},
{sex: "female", name: "B", read: false},
{sex: "female", name: "A", read: true},
{sex: "male", name: "A", read: false},
{sex: "male", name: "B", read: false},
{sex: "female", name: "B", read: true},
{sex: "male", name: "A", read: true},
{sex: "female", name: "A", read: false},
{sex: "male", name: "B", read: true}
]
let sorted;
sorted = arr.sort((a, b) => a.read - b.read );
console.log('----- неправильный вариант ------')
sorted.forEach(e => {
console.log(JSON.stringify(e))
})
console.log('\n----- правильный вариант ------')
/* не все сортировки правильны
только по ключу 'read'
[
{"sex":"male","name":"B","read":false}
{"sex":"female","name":"B","read":false}
{"sex":"male","name":"A","read":false}
{"sex":"male","name":"B","read":false}
{"sex":"female","name":"A","read":false}
{"sex":"female","name":"B","read":true}
{"sex":"female","name":"A","read":true}
{"sex":"female","name":"B","read":true}
{"sex":"male","name":"A","read":true}
{"sex":"male","name":"B","read":true}
]
*/
sorted = arr.sort((a, b) => {
let ta = 0, tb = 0;
const test = (a, b) => {
if (a === b) return 0;
if(typeof a == 'string') return (a < b) ? -1 : 1
return Math.sign(a - b);
}
ta += test(a.read, b.read) * 1000 // умножается на приоритет
tb += test(b.read, a.read) * 1000 // больше число - больше приоритет
ta += test(a.sex, b.sex) * 100 // умножается на приоритет
tb += test(b.sex, a.sex) * 100 // больше число - больше приоритет
ta += test(a.name, b.name) * 10 // умножается на приоритет
tb += test(b.name, a.name) * 10 // больше число - больше приоритет
return (ta >= tb ? 1 : -1 )
});
sorted.forEach(e => {
console.log(JSON.stringify(e))
})
/*
все сортировки правильны
првая выполнена по 'read'
вторая по sex (первое поле в `таблице``)
третья по имени (второе поле в `таблице``)
{"sex":"female","name":"A","read":false}
{"sex":"female","name":"B","read":false}
{"sex":"male","name":"A","read":false}
{"sex":"male","name":"B","read":false}
{"sex":"male","name":"B","read":false}
{"sex":"female","name":"A","read":true}
{"sex":"female","name":"B","read":true}
{"sex":"female","name":"B","read":true}
{"sex":"male","name":"A","read":true}
{"sex":"male","name":"B","read":true}
*/