原文:https://www.youtube.com/watch?v=zVevl-K-m7Y
译者:前端小智

为了保证的可读性,本文采用意译而非直译。

想优质文章请猛戳GitHub博客,一年百来篇优质文章等着你!

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

在此之前先简单介绍一下 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"})
);

运行结果:

代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log 调试,这边顺便给大家推荐一个好用的BUG监控工具 Fundebug。

交流

干货系列文章汇总如下,觉得不错点个Star,欢迎 加群 互相学习。

https://github.com/qq449245884/xiaozhi

我是小智,公众号「大迁世界」作者,对前端技术保持学习爱好者。我会经常分享自己所学所看的干货,在进阶的路上,共勉!

关注公众号,后台回复福利,即可看到福利,你懂的。

spreadsheet js中创建下拉列表_JS 中创建自定义排序方法相关推荐

  1. js 浅拷贝直接赋值_JS中实现浅拷贝和深拷贝的代码详解

    (一)JS中基本类型和引用类型 JavaScript的变量中包含两种类型的值:基本类型值 和 引用类型值,在内存中的表现形式在于:前者是存储在栈中的一些简单的数据段,后者则是保存在堆内存中的一个对象. ...

  2. js混淆还原工具_js混淆解密 还原混淆方法

    方法一: 利用IE开发人员工具(IE8开始已经自带,IE7以前需要下载安装IE Developer Toolbar)进行反混淆. 方法二: 混淆后的测试代码: eval(function(p,a,c, ...

  3. js 上下箭头滚动_JS中的this完全讲解,再也不会被this搞晕了

    关于This对象 js 中的this 是一个比较难理解的对象:所以也经常作为面试的考点,考察应聘者的js 基础能力:其实this的指向也就那么几种情况,接下来我们一一看一下: 函数中的this取何值是 ...

  4. js 浅拷贝直接赋值_JS中的赋值、浅拷贝与深拷贝

    作者:奚杰 拷贝是写代码中经常使用的方法.浅拷贝与深拷贝是指拷贝的两种情况.本文将深入探究JS的赋值.浅拷贝与深拷贝. 数据类型 在探究深拷贝与浅拷贝之前,我们先梳理一下JS的数据类型.在JavaSc ...

  5. java数组 js数组的长度_js中split()方法得到的数组长度问题

    定义和用法 split() 方法用于把一个字符串分割成字符串数组. 语法 stringObject.split(separator,howmany) 参数 描述 separator 必需.字符串或正则 ...

  6. js删除数组中指定元素_js中数组操作详解

    今天给大家带来一篇有关数组操作方法的文章. 新建数组 方法一:通过new运算符创建一个数组构造函数. var arr = new Array(); 方法二:通过方括号直接创建直接量数组. var ar ...

  7. chrome js 读取文件夹_JS读取/创建本地文件及目录文件夹的方法

    注:以下操作只在IE下有效! Javascript是网页制作中离不开的脚本语言,依靠它,一个网页的内容才生动活泼.富有朝气.但也许你还没有发现并应用它的一些更高级的功能吧?比如,对文件和文件夹进行读. ...

  8. jq js json 转字符串_JS中JSON对象和String之间的互转及处理技巧

    json:JavaScript 对象表示法(javascript Object Notation),其实JSON就是一个javaScript的对象(Object)而已. 如有不清楚JSON,可以去w3 ...

  9. js 多个定时器_JS中的同步/异步编程

    1. 进程(process)/线程(thread) 进程process: 电脑端安装很多的应用软件,每当运行一个应用程序,相当于开辟一个进程(而对于浏览器来说,每新建一个页卡访问一个页面,都是新开辟一 ...

最新文章

  1. 阿里的御用框架,它非常牛啤!不服不行!
  2. RDKit | 基于RDKit从分子中提取3D药效团特征
  3. dos命令行设置网络优先级_海康威视二层接入网络交换机DS-3E2326-H 26口_DS-3E2326-H_DS-3E2326-H...
  4. token验证_java基于token的身份验证?读完之后,大部分程序员收藏了...
  5. Oracle 查看sql语句执行计划方法
  6. PPT 下载 | 神策数据曹犟:数据驱动从方法到实践
  7. SpringBoot整合mybatis进行快速开发
  8. Java中Web程序修改配置文件不重启服务器的方法
  9. 阿里云ECS家族再添新成员,推出密集计算型实例规格族ic5
  10. C++或C 实现AES ECB模式加密解密,支持官方验证
  11. python数据生成可视化_Python数据分析:手把手教你用Pandas生成可视化图表
  12. 全新起航,无悔青春-嵌入式19031开班典礼
  13. 基础集合论 第三章 2 自然数集
  14. 电脑鼠标单击变成了双击如何恢复
  15. matlab插值与拟合例题_数学建模matlab插值与拟合
  16. 4874: 筐子放球
  17. 作为一个新手程序员该如何成长
  18. libvirt零知识学习4 —— libvirt源码编译安装(2)
  19. 追忆第一次南下深圳有哪些重大抉择(二)?
  20. linux环境变量设置图解,Ubuntu Linux 各个环境变量配置文件详解, 环境变量PATH设置...

热门文章

  1. HDU 6124 Euler theorem
  2. Spring入门(1)
  3. 最近让我焦灼的四个问题
  4. linux查看java jdk安装路径
  5. Silverlight 游戏开发小技巧:技能冷却效果1(Cooldown)
  6. java基础知识简化
  7. 13数据库表空间回收
  8. C# WPF 多个window 相互覆盖的次序控制 不用topmost
  9. BZOJ 4826: [Hnoi2017]影魔 单调栈 主席树
  10. [置顶] VS自带工具:dumpbin的使用