我在使用基本值对 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/