У меня есть массив, организованный как таковой.
const array = [
{
Year: 2018,
Month: 'Dec'
},
{
Year: 2017,
Month: 'Apr'
},
{
Year: 2018,
Month: 'Mar'
},
{
Year: 2018,
Month: 'Oct'
},
{
Year: 2017,
Month: 'Jan'
},
{
Year: 2018,
Month: 'Apr'
}
]
Я успешно организовал данные по годам или по месяцам, но каждый раз, когда я пытаюсь организовать их по обоим сразу, то тот, кто организовал данные последним, заменит все, что было до них. Я понимаю, почему он это делает, но не могу найти способ обойти это.
const sortedByYear = array.sort((a, b) => a.Year - b.Year);
Сортировать по годам довольно просто.
const sorted = sortedByYear.sort((a, b) => Months.indexOf(a.Month) - Months.indexOf(b.Month));
Сортирует по месяцам.
Я попытался добавить какую-то проверку в средство проверки месяца, если годы совпадают, тогда прибегайте, но это не решает проблему того, как он будет сортировать.
Это забавный вариант использования контравариантные функторы - я поделюсь ответом, демонстрирующим мульти-сортировку, подобную той, которую вы пытаетесь достичь здесь: stackoverflow.com/a/47640811/633183
Вам нужно будет поместить тесты оба в вашу функцию sort
:
const input = [
{
Year: 2018,
Month: 'Dec'
},
{
Year: 2017,
Month: 'Apr'
},
{
Year: 2018,
Month: 'Mar'
},
{
Year: 2018,
Month: 'Oct'
},
{
Year: 2017,
Month: 'Jan'
},
{
Year: 2018,
Month: 'Apr'
}
];
const Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
input.sort((a, b) => {
if (a.Year !== b.Year) return a.Year - b.Year;
return Months.indexOf(a.Month) - Months.indexOf(b.Month)
});
console.info(input);
Вы можете использовать lodash sortBy и передавать поля, которые вы хотите, в Сортировать по в виде массива.
const sorted = _.sortBy(array, ['Year', 'Month']);
Вы можете использовать комбинацию year
и month
для формирования критериев сравнения. padStart не будет работать в IE, поэтому для этого вам может понадобиться полифилл.
const input = [
{
Year: 2018,
Month: 'Dec'
},
{
Year: 2017,
Month: 'Apr'
},
{
Year: 2018,
Month: 'Mar'
},
{
Year: 2018,
Month: 'Oct'
},
{
Year: 2017,
Month: 'Jan'
},
{
Year: 2018,
Month: 'Apr'
}
];
const Months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
input.sort((a, b) =>`${a.Year}${Months.indexOf(a.Month).toString().padStart(2,0)}` - `${b.Year}${Months.indexOf(b.Month).toString().padStart(2,0)}`
);
console.info(input);
Сортировать по годам, если совпадают - по месяцам.