Javascript 按等级列表对数组进行排序

标签 javascript

我在使用基本值对 JS 数组进行排序方面有一些经验,但这一次让我难住了。我有一个消防员对象数组,每个对象都有一个 rank: 属性以及常用属性,例如 firstName: foo, lastName: bar

我想按消防员等级对数组进行排序,但是等级不遵循字母顺序。我希望它们按以下顺序排序:

CFO - Chief Fire Officer
DCFO - Deputy Chief Fire Officer
SSO - Senior Station Officer
SO - Station Officer
SFF - Senior Firefighter
QFF - Qualified Firefighter
FF - Firefighter
RFF - Recruit Firefighter
OS - Operational Support

我还没有尝试过任何事情,我不知道从哪里开始。任何帮助将不胜感激!

最佳答案

你首先需要一个军官的军衔引用,越高权重越大。因此,让我们创建一个散列并以某种方式对它进行排序。为此,我将选择降序,因为您已经提供了:

let ranks = {
  CFO: 1,
  DCFO: 2,
  SSO: 3,
  SO: 4,
  SFF: 5,
  QFF: 6,
  FF: 7,
  RFF: 8,
  OS: 9
}

接下来,我们要按级别组织军官数组,因此我们需要一个比较函数

compareRank( left, right ){
  return ranks[left.rank] - ranks[right.rank]
}

接下来我们需要通过排序函数对数组进行排序

let sortedOfficers = officers.sort(compareRank)

它们现在将按降序排序(实际上是升序,但是我们给予较高的排名较小的值,因此它是相反的)。


另一种排序方法包括按照您想要的顺序串联列表排名,并根据您想要的排名进行排序

function fieldIs(key, value){ return function(object){ return object[key] == value } }

let sortedOfficers = [].concatenate(
  officers.filter(fieldIs('rank', 'CFO'),
  officers.filter(fieldIs('rank', 'DCFO'),
  officers.filter(fieldIs('rank', 'SSO'),
  officers.filter(fieldIs('rank', 'SO'),
  officers.filter(fieldIs('rank', 'SFF'),
  officers.filter(fieldIs('rank', 'QFF'),
  officers.filter(fieldIs('rank', 'FF'),
  officers.filter(fieldIs('rank', 'RFF'),
  officers.filter(fieldIs('rank', 'OS')
)

此方法虽然更冗长且慢得多,但适应性更强,因为您可以根据字段的输入有序值数组轻松组成各个部分成为

function fieldSort(field, orderedValues, things){
  return  [].concatenate(
    ...orderedValues.map(value =>
      things.filter(
        fieldIs(
          field,
          value
         )
      )
    )
}

当然还有其他排序方式,但这些只是一些示例,旨在帮助说明如果您有某种顺序定义,则可以根据该顺序进行排序。现在真正的问题是,如何根据在 orderedValues 数组上使用 Array.prototype.reduce() 可用于创建该哈希的想法来组合这两种方法在第一个例子中?

让我们尝试一下:

function fieldSort(field, orderedValues, things){
  let valueHash = orderedValues.reduce((acc, value, index) =>{
      acc[value] = index
      return acc
    },
    {}
  )
  return things.sort((left, right) =>
    valueHash[left[field]] - valueHash[right[field]]
  )
}

关于第三个选项的好消息:它删除了第二个选项的所有循环。它只循环对有序数组进行排序+一次循环所需的次数。通过借鉴第一个示例的想法,这使得它比第二个示例快得多。

关于Javascript 按等级列表对数组进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50940166/

相关文章:

javascript - AJAX get() 数据

javascript - 返回具有编辑对象属性的新 redux 状态

javascript - 将弹出窗口绑定(bind)到 Leaflet.js 中的动态标记列表

javascript - vis.js - 如何运行 getSeed() 方法

javascript - 打开前选择2 scrollIntoView

javascript - 在主体淡出之前存储滚动位置,然后在主体淡入之后返回滚动位置?

javascript - 术语 "global property"和 "global variable"是同义词吗?

javascript - 拖放 div

Javascript 连接数字,而不是相加

javascript - iFrame overflow-x BUG 在 Chrome、IE、Opera、Safari 但在 Firefox 上没有