资讯专栏INFORMATION COLUMN

JS 中创建自定义排序方法

shiyang6017 / 1801人阅读

摘要:想阅读更多优质文章请猛戳博客一年百来篇优质文章等着你一般情况咱们排序大都按数字或字母顺序,但也有一些情况下,咱们可能需要自定义排序顺序。数组中正在处理的元素。

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

想阅读更多优质文章请猛戳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。

原文:https://www.youtube.com/watch...

交流

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

https://github.com/qq44924588...

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/106784.html

相关文章

  • 2017-08-06 前端日报

    摘要:前端日报精选前端实现文件的断点续传精读最佳前端面试题及面试官技巧渲染机制解析十日谈第一日绘制随机不规则三角彩条小谈个人主页的实现发布中文译使用被认为是有害的了解的命令掘金译文档序言及章上北欧小镇的前端小船译文档 2017-08-06 前端日报 精选 前端实现文件的断点续传精读《最佳前端面试题》及面试官技巧React 渲染机制解析【React Native十日谈】第一日绘制随机不规则三角...

    z2xy 评论0 收藏0
  • 【Docker实战入门学习笔记】什么是docker?

    摘要:实现前述目的的方式有两种在一个文件中指定一个基础镜像及需要完成的修改或通过运行一个镜像,对其进行修改并提交。容器对外公开服务是必要的,因此允许公开容器的特定端口。镜像必须完全可移植,不允许例外。 Docker是一个相对较新且发展非常快速的项目,可用来创建非常轻量的虚拟机。注意,这里的引号非常重要,Docker创建的并非真正的虚拟机,而更像是打了激素的chroot,嗯,是大量的激素。 D...

    seanHai 评论0 收藏0
  • XML 实体扩展攻击

    摘要:虽说可以通过上述方式进行防御,远程实体扩展通过使解析器发出远程请求来获得被引用实体的扩展值来进行攻击。返回结果将自行定义其他解析器必须另行请求的外部实体。 XMl Entity Expansion(攻击)某种程度上类似于 XML Entity Expansion,但是它主要试图通过消耗目标程序的服务器环境来进行DOS攻击的。这种攻击基于XML Entity Expansion实现,通过...

    TerryCai 评论0 收藏0
  • Jest + Enzyme 前端自动化测试

    摘要:简介是发布的一个开源的基于框架的单元测试工具。具体版本对照如下版本版本此处使用的版本为,所以我们需要安装依赖安装完成,接下来需要进行相关的配置。这样就可以将测试集中在组件的结构和逻辑上。 Jest、Enzyme 简介 Jest 是 Facebook 发布的一个开源的、基于 Jasmine 框架的 JavaScript 单元测试工具。 Enzyme 是 React 的测试类库。 Enzy...

    xushaojieaaa 评论0 收藏0
  • 观察者设计模式

    摘要:定义观察者设计模式中有一个对象被称为根据观察者维护一个对象列表,自动通知它们对状态的任何修改。与观察者模式不同,它允许任何订阅者实现一个适当的事件处理程序来注册并接收发布者发布的主题通知。 观察者设计模式是一个好的设计模式,这个模式我们在开发中比较常见,尤其是它的变形模式订阅/发布者模式我们更是很熟悉,在我们所熟悉jQuery库和vue.js框架中我们都有体现。我在面试中也曾经被问到o...

    kviccn 评论0 收藏0

发表评论

0条评论

shiyang6017

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<