我有一些用基本值对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
)
)
)
}
当然,可能还有其他排序方式,但是这些只是一些示例,可以帮助您证明,如果您对订单有某种定义,则可以基于该订单进行排序。现在,真正的问题变成了如何在第一个示例中基于可以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]]
)
}
关于第三个选项的好消息:它删除了第二个选项中的所有循环。它仅按排序循环所需的次数循环+在有序数组上循环一次。通过采用第一个示例中的思想,这使其比第二个示例快得多。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句