我有一些对具有基本值的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
我还没有尝试过任何东西,也不知道从哪里开始。任何帮助将不胜感激!
答案 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]]
)
}
有关第三个选项的好消息:它删除了第二个选项中的所有循环。它仅按排序循环所需的次数循环+在有序数组上循环一次。通过采用第一个示例中的思想,这比第二个示例要快得多。