ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JS 中创建自定义排序方法

2019-09-20 16:55:24  阅读:181  来源: 互联网

标签:status const 自定义 title JS item Job sortBy 排序


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


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


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


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


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


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


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


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


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"

  })

);

运行结果:




标签:status,const,自定义,title,JS,item,Job,sortBy,排序
来源: https://blog.51cto.com/14516511/2439727

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有