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

Javascript按列组列表对数组进行排序,javascript,Javascript,我有一些用基本值对JS数组进行排序的经验,但这一点让我感到困惑。我有一个消防员对象数组,每个对象都有一个rank:属性以及像firstName:foo,lastName:bar这样的常用属性 我想按消防员级别对数组进行排序,但是级别不按照字母顺序排列。我希望它们按以下顺序排序: CFO - Chief Fire Officer DCFO - Deputy Chief Fire Officer SSO - Senior Station Officer SO - Station Officer SF

我有一些用基本值对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]
}
接下来,我们需要通过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
         )
      )
    )
}

当然,还有其他的排序方法,但这些只是几个例子,可以帮助说明,如果你对顺序有某种定义,你可以根据这个顺序进行排序。现在真正的问题是,在第一个示例中,可以使用
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]]
  )
}

关于第三个选项的好消息是:它删除了第二个选项中的所有循环。它只根据需要在有序数组上排序+一个循环。这使得它比第二个例子快得多,因为它采用了第一个例子中的想法。

只需比较上面数组中每个项目的
索引?使用
map
以提高效率?每个级别将有多个级别,我希望他们按该顺序分组。我不认为有问题,应该仍然可以正常工作。。?如果您想发布输入,请显示此方法的数组,同时显示更详细的。。。我不在乎冗长,我更在乎O(n^2)的时间复杂度与
.sort()
的O(n log n)的时间复杂度。尽管如此,我还是对第一种方法投了赞成票,因为这正是我应该做的。你可以考虑的一个很好的小片段,包括如何将一个行列数组转换成一开始的对象,比如:<代码> const秩= [ CFO’,'DCFO ',…]。
我没有特别提到这一点,因为我想把它作为一个额外的“思考更多”的东西添加进去。。。但是无聊的。我可以把这个加进去。第二种方法是缓慢的,是的,但更多的人习惯于这样思考。我应该加上一个免责声明,汉克斯,我认为这比一个基本的、令人敬畏的答案要复杂一些。