Javascript按行列排序数组

时间:2018-06-20 04:21:07

标签: 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

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

1 个答案:

答案 0 :(得分:2)

首先,您需要一个有关军官职位的参考,越高,权重越大。因此,让我们进行哈希处理并按某种等级对其进行排序。为此,我将选择一个降序,因为您已经提供了它:

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]
}

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

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
         )
      )
    )
}

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

让我们尝试一下:

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]]
  )
}

有关第三个选项的好消息:它删除了第二个选项中的所有循环。它仅按排序循环所需的次数循环+在有序数组上循环一次。通过采用第一个示例中的思想,这比第二个示例要快得多。