我有一个具有几个键值对的对象数组,我需要根据'updated_at'对它们进行排序:
[
{
"updated_at" : "2012-01-01T06:25:24Z",
"foo" : "bar"
},
{
"updated_at" : "2012-01-09T11:25:13Z",
"foo" : "bar"
},
{
"updated_at" : "2012-01-05T04:13:24Z",
"foo" : "bar"
}
]
最有效的方法是什么?
我已经在Typescript中创建了一个排序函数,我们可以使用它来搜索字符串,日期和对象数组中的数字。它还可以对多个字段进行排序。
export type SortType = 'string' | 'number' | 'date';
export type SortingOrder = 'asc' | 'desc';
export interface SortOptions {
sortByKey: string;
sortType?: SortType;
sortingOrder?: SortingOrder;
}
class CustomSorting {
static sortArrayOfObjects(fields: SortOptions[] = [{sortByKey: 'value', sortType: 'string', sortingOrder: 'desc'}]) {
return (a, b) => fields
.map((field) => {
if (!a[field.sortByKey] || !b[field.sortByKey]) {
return 0;
}
const direction = field.sortingOrder === 'asc' ? 1 : -1;
let firstValue;
let secondValue;
if (field.sortType === 'string') {
firstValue = a[field.sortByKey].toUpperCase();
secondValue = b[field.sortByKey].toUpperCase();
} else if (field.sortType === 'number') {
firstValue = parseInt(a[field.sortByKey], 10);
secondValue = parseInt(b[field.sortByKey], 10);
} else if (field.sortType === 'date') {
firstValue = new Date(a[field.sortByKey]);
secondValue = new Date(b[field.sortByKey]);
}
return firstValue > secondValue ? direction : firstValue < secondValue ? -(direction) : 0;
})
.reduce((pos, neg) => pos ? pos : neg, 0);
}
}
}
用法:
const sortOptions = [{
sortByKey: 'anyKey',
sortType: 'string',
sortingOrder: 'asc',
}];
arrayOfObjects.sort(CustomSorting.sortArrayOfObjects(sortOptions));
使用array .sort()对数组进行排序
克隆数组使用展开运算符(…)使函数纯
按所需键排序(updated_at)
将日期字符串转换为日期对象
Array.sort()的工作原理是,如果current项和next项是一个可以执行无节奏操作的数字/对象,则从current项和next项中减去两个属性
const input = [
{
updated_at: '2012-01-01T06:25:24Z',
foo: 'bar',
},
{
updated_at: '2012-01-09T11:25:13Z',
foo: 'bar',
},
{
updated_at: '2012-01-05T04:13:24Z',
foo: 'bar',
}
];
const sortByUpdatedAt = (items) => [...items].sort((itemA, itemB) => new Date(itemA.updated_at) - new Date(itemB.updated_at));
const output = sortByUpdatedAt(input);
console.log(input);
/*
[ { updated_at: '2012-01-01T06:25:24Z', foo: 'bar' },
{ updated_at: '2012-01-09T11:25:13Z', foo: 'bar' },
{ updated_at: '2012-01-05T04:13:24Z', foo: 'bar' } ]
*/
console.log(output)
/*
[ { updated_at: '2012-01-01T06:25:24Z', foo: 'bar' },
{ updated_at: '2012-01-05T04:13:24Z', foo: 'bar' },
{ updated_at: '2012-01-09T11:25:13Z', foo: 'bar' } ]
*/
我说得有点晚了,但在2021年,正确的答案是使用inter . collator。updated_at是一个ISO-8601字符串,因此可以作为字符串进行排序。转换为Date是一种浪费时间的操作,如果手动比较返回0、1或-1也是如此。
const arr = [
{
"updated_at": "2012-01-01T06:25:24Z",
"foo": "bar"
},
{
"updated_at": "2012-01-09T11:25:13Z",
"foo": "bar"
},
{
"updated_at": "2012-01-05T04:13:24Z",
"foo": "bar"
}
];
const { compare } = Intl.Collator('en-US');
arr.sort((a, b) => compare(a.updated_at, b.updated_at));
Intl。Collator返回一个函数,可以用作#Array.sort的compareFunction。因为我们在对一个对象排序,所以我们调用compare函数与我们要排序的键的值进行比较。
注意,如果我们对一个字符串数组排序,我们可以简单地这样做:
arr.sort(compare);
还要注意,正如其他人指出的那样,sort会使原始数组发生变异。如果这是不可取的,您可能希望首先克隆它。在2021年,你可以这样做:
[...arr].sort((a, b) => compare(a.updated_at, b.updated_at));