为了保证的可读性,本文采用意译而非直译。前端
想阅读更多优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!git
通常状况我们排序大都按数字或字母顺序,但也有一些状况下,我们可能须要自定义排序顺序。github
在此以前先简单介绍一下 reduce
方法:数组
语法:arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
函数
callback:执行数组中每一个值的函数,包含四个参数:工具
accumulator:累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue
(见于下方)。学习
currentValue:数组中正在处理的元素。spa
currentIndex (可选):数组中正在处理的当前元素的索引。 若是提供了initialValue
,则起始索引号为0
,不然为1
。debug
array(可选): 调用 reduce()
的数组调试
initialValue(可选):做为第一次调用 callback
函数时的第一个参数的值。 若是没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce
将报错。
rudeuce 过程描述:
回调函数第一次执行时,accumulator
和currentValue
的取值有两种状况:若是调用reduce()
时提供了initialValue
,accumulator
取值为initialValue
,currentValue
取数组中的第一个值;若是没有提供 initialValue
,那么accumulator
取数组中的第一个值,currentValue
取数组中的第二个值。
回到原文:
以下面的例子所示,我们想让 inProgress
在第一位,接着是 todo
,而后是 done
。
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'}))
这样就能够按照我们的自定义顺序排序,不过还有一个问题,若是列表中有一个status
不一样的项(不在我们的排序顺序中),就会出现问题。所以,为了处理这个问题,我们须要设置一个默认的sort
字段来捕获排序中不须要的全部项。
const tasksWithDefault = tasks.map(item => ( { ...item, sortStatus: sortBy.includes(item.status) ? item.status:'other' }) )
此次传递的是更新后的sort
字段,那么如今就有了正确的排序顺序,列表底部还有包含状态为 other
的项目。
完整代码:
const tasks = [ { id: 1, title: "Job A", status: "done" }, { id: 2, title: "Job B", status: "inProgress" }, { id: 3, title: "Job C", status: "todo" }, { id: 3, title: "Job D", status: "onHold" }, { id: 4, title: "Job E", status: "inProgress" }, { id: 5, title: "Job F", status: "todo" } ]; const sortBy = ["inProgress", "todo", "done"]; 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]] ); }; const tasksWithDefault = tasks.map(item => ({ ...item, sortStatus: sortBy.includes(item.status) ? item.status : "other" })); console.log( customSort({ data: tasksWithDefault, sortBy: [...sortBy, "other"], sortField: "sortStatus" }) );
运行结果:
代码部署后可能存在的BUG无法实时知道,过后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给你们推荐一个好用的BUG监控工具 Fundebug。
原文:https://www.youtube.com/watch...
干货系列文章汇总以下,以为不错点个Star,欢迎 加群 互相学习。
https://github.com/qq44924588...
我是小智,公众号「大迁世界」做者,对前端技术保持学习爱好者。我会常常分享本身所学所看的干货,在进阶的路上,共勉!
关注公众号,后台回复福利,便可看到福利,你懂的。