1. 首页
  2. 前端进阶
  3. JavaScript

JavaScript 中创建自定义排序方法

一般情况咱们排序大都按数字或字母顺序,但也有一些情况下,咱们可能需要自定义排序顺序。

在此之前先简单介绍一下 reduce 方法:

语法:arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])

callback:执行数组中每个值的函数,包含四个参数:

accumulator:累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。

currentValue:数组中正在处理的元素。

currentIndex (可选):数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则为1

array(可选): 调用 reduce() 的数组

initialValue(可选):作为第一次调用 callback 函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。

rudeuce 过程描述:

回调函数第一次执行时,accumulatorcurrentValue的取值有两种情况:如果调用reduce()时提供了initialValueaccumulator取值为initialValuecurrentValue取数组中的第一个值;如果没有提供 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" }) );

运行结果:

码农进阶题库,每天一道面试题 or Js小知识

*

码农进阶题库,每天一道面试题 or Js小知识 https://www.javascriptc.com/interview-tips/

作者:前端小智
链接:https://www.youtube.com/watch?v=zVevl-K-m7Y

看完两件小事

如果你觉得这篇文章对你挺有启发,我想请你帮我两个小忙:

  1. 关注我们的 GitHub 博客,让我们成为长期关系
  2. 把这篇文章分享给你的朋友 / 交流群,让更多的人看到,一起进步,一起成长!
  3. 关注公众号 「IT平头哥联盟」,公众号后台回复「资源」 免费领取我精心整理的前端进阶资源教程

JS中文网是中国领先的新一代开发者社区和专业的技术媒体,一个帮助开发者成长的社区,目前已经覆盖和服务了超过 300 万开发者,你每天都可以在这里找到技术世界的头条内容。欢迎热爱技术的你一起加入交流与学习,JS中文网的使命是帮助开发者用代码改变世界

本文著作权归作者所有,如若转载,请注明出处

转载请注明:文章转载自「 Js中文网 · 前端进阶资源教程 」https://www.javascriptc.com

标题:JavaScript 中创建自定义排序方法

链接:https://www.javascriptc.com/3519.html

« JavaScript 精粹:Number 与 Math
吃透移动端 H5 响应式布局»
Flutter 中文教程资源

相关推荐

QR code