如何在 JavaScript 中创建自定义排序方式
通常我们会按数值或字母顺序对数组进行排序,但有时我们也可能需要自定义排序顺序。
以下示例希望首先显示正在进行中的项目,然后显示待办事项,最后显示已完成的项目。
const tasks = [
{id:1, title: 'Job A', status: 'done'},
{id:2, title: 'Job B', status: 'inProgress'},
{id:3, title: 'Job C', status: 'todo'},
{id:4, title: 'Job D', status: 'inProgress'},
{id:5, title: 'Job E', status: 'todo'}
]
我们首先创建一个按所需排序顺序排列的数组。
const sortBy = ['inProgress', 'todo', 'done']
然后我们将使用reduce创建一个函数,该函数会将数据输出为一个对象,{inProgress: 0, todo: 1, done: 2}其中数组项作为键,索引作为值。
const sortByObject = data => data.reduce(
(obj,item,index) => ({
...obj,
[item]:index
}), {}
)
console.log(sortByObject(sortBy))
/* {inProgress: 0, todo: 1, done: 2} */
现在我们有了排序设置,我们可以用一个可重用的函数将所有内容整合在一起,该函数传入一个数组(data)、一个sortby数组和一个,sortField这样我们就知道要按哪个字段排序。
const customSort = ({data, sortBy, sortField}) => {
const sortByObject = sortBy.reduce(
(obj, item, index) => ({
...obj,
[item]: index
}), {})
return data.sort((a, b) => sortByObject[a[sortField]] - sortByObject[b[sortField]])
}
console.log(customSort({data:tasks, sortBy, sortField: 'status'}))
现在列表将按照我们自定义的顺序排序,但是如果列表中存在状态不同的项目(即不在我们自定义排序顺序中的项目),就会出现问题。为了解决这个问题,我们将设置一个默认排序字段,用于捕获所有我们不希望被排序的项目。
const tasksWithDefault = tasks.map(item => ({...item, sortStatus: sortBy.includes(item.status) ? item.status:'other'}))
如此一来,如果我们再次退出函数,这次传入更新后的排序字段,那么我们现在就有了正确的排序顺序,其他项目则位于列表底部。
console.log(customSort({
data:tasksWithDefault,
sortBy: [...sortBy,'other'],
sortField: 'sortStatus'
}))
如果您想了解更多技巧,或者想在我的下一篇文章发布时收到通知,请在这里关注我:
Instagram
Facebook
afewminutesofcode.com
Twitter
Pinterest