Я новичок в JavaScript, и у меня есть массив объектов JSON с некоторыми атрибутами. Я хочу отсортировать его по атрибуту даты, который может быть либо date, либо bool. Думаю, пример поможет вам понять мою проблему.
[
{
"name":"Name 1",
"photoUrl":"URL",
"date" : false,
"bool": false
},
{
"name":"Name2",
"photoUrl":"URL",
"date" : false,
"bool": false
},
{
"name":"Name 3",
"photoUrl":"URL",
"date" : "1.6. 2020",
"bool": true
},
{
"name":"Name 4",
"photoUrl":"",
"date" : "25.9. 2020",
"bool": true
},
{
"name":"Name 5",
"photoUrl":"",
"date" : "29.8. 2020",
"bool": true
},
{
"name":"Name 6",
"photoUrl":"",
"date" : "4.7. 2020",
"bool": true
},
{
"name":"Name 7",
"photoUrl":"",
"date" : "25.6. 2020",
"bool": true
},
{
"name":"Name 8",
"photoUrl":"",
"date" : "22.2. 2021",
"bool": true
},
]
Я могу изменить структуру данных, как хочу. По сути, я хочу, чтобы те, у которых дата не была ложной, поверх моего массива и отсортированные по дате (самые новые сверху), а затем следовали тем, у которых дата ложная, но я не могу найти способ сделать это.
Большое спасибо за любую помощь.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


var ls = [
{
"name":"Name 1",
"photoUrl":"URL",
"date" : false,
"bool": false
},
{
"name":"Name2",
"photoUrl":"URL",
"date" : false,
"bool": false
},
{
"name":"Name 3",
"photoUrl":"URL",
"date" : "1.6. 2020",
"bool": true
},
{
"name":"Name 4",
"photoUrl":"",
"date" : "25.9. 2020",
"bool": true
},
{
"name":"Name 5",
"photoUrl":"",
"date" : "29.8. 2020",
"bool": true
},
{
"name":"Name 6",
"photoUrl":"",
"date" : "4.7. 2020",
"bool": true
},
{
"name":"Name 7",
"photoUrl":"",
"date" : "25.6. 2020",
"bool": true
},
{
"name":"Name 8",
"photoUrl":"",
"date" : "22.2. 2021",
"bool": true
},
];
function customSort(ls){
var lsWithDatesAsBool = ls.filter((obj)=>{ return (typeof(obj.date)= = "boolean") });
var lsWithDatesAsNotBool = ls.filter((obj)=>{ return !(typeof(obj.date)= = "boolean") });
lsWithDatesAsNotBool.sort((a, b) => (convertToProperDate(a.date) < convertToProperDate(b.date)) ? 1 : -1)
return lsWithDatesAsNotBool.concat(lsWithDatesAsBool);
}
function convertToProperDate(d)
{
var arr = d.split(".");
var day = arr[0].trim();
var month=arr[1].trim();
var year = arr[2].trim();
console.info(year+"-"+(month.length==1?("0"+month):month)+"-"+(day.length==1?("0"+day):day))
return new Date(year+"-"+(month.length==1?("0"+month):month)+"-"+(day.length==1?("0"+day):day))
}
console.info(customSort(ls));
@ krystof18, это потому, что у вас неправильный формат даты, поэтому сортировка неточная. Обновили решение сейчас, надеюсь, это поможет !!
Все скобки и скобки в (obj)=>{ return (typeof(obj.date)= = "boolean") } избыточны, используйте obj => typeof obj.date == 'boolean'.
В синтаксическом анализаторе даты нет смысла преобразовывать строку в другую строку, которая затем анализируется встроенным синтаксическим анализатором как UTC. Рассмотрим let [d, m, y] = d.split(/\D+/); return new Date(y, m-1, d), чтобы полностью отказаться от встроенного синтаксического анализатора. \D+ разбивается на один или несколько нецифровых символов для обработки таких случаев, как «25.6. 2020».
Я тоже новичок, и это сработало, возможно, это не лучшая практика.
const data = [
{
name: "Name 1",
photoUrl: "URL",
date: false,
bool: false,
},
{
name: "Name2",
photoUrl: "URL",
date: false,
bool: false,
},
{
name: "Name 3",
photoUrl: "URL",
date: "1.6. 2020",
bool: true,
},
{
name: "Name 4",
photoUrl: "",
date: "25.9. 2020",
bool: true,
},
];
const sortingData = () => {
let sortedData = [];
//Getting data with date and adding them to the empty array.
for (let i = 0; i < data.length; i++) {
if (data[i].date) {
sortedData.push(data[i]);
}
}
//Sorting from new to old.
sortedData.sort((a, b) => (a.date < b.date ? 1 : -1));
//Getting data with no date and adding them to the new array.
for (let i = 0; i < data.length; i++) {
if (data[i].date === false) {
sortedData.push(data[i]);
}
}
return sortedData;
};
Это работает, но если я добавлю больше данных (я обновил вопрос, добавив больше данных), он не будет работать правильно, это мое плохо, я думал, что меньше данных достаточно хорошо, чтобы заставить его работать.
Нет, это не «работает», потому что даты в формате d.m.y не сортируются лексически. Формат вроде гггг-мм-дд делает. Кроме того, функция сортировки должна возвращать 0, когда a.date == b.date, ваша функция возвращает 1, как и (a, b) => a.date < b.date.
Это работает, но если я добавлю больше данных (я обновил вопрос, добавив больше данных), он не будет работать правильно, это мое плохо, я думал, что меньше данных достаточно хорошо, чтобы заставить его работать.