【问题标题】:JS Sort by specific sort orderJS 按特定排序顺序排序
【发布时间】:2018-03-28 15:36:49
【问题描述】:

我需要按如下所示的特定顺序对数据进行排序。

const sortBy = ['b','a','c','e','d']
const data = ['a','d','e']

我知道如何按升序/降序排序

console.log(data.sort((a, b) => a > b)) //["a", "d", "e"]
console.log(data.sort((a, b) => a < b)) //["e", "d", "a"]

但是是否可以使用.sort 按特定顺序排序? 例如,低于我想要的订单是sortBy

我目前正在通过在我的排序数组和我的数据之间创建一个公共项目数组来实现这一点。

const commonItems = getCommonItemsInArrays(sortBy,data)
console.log(commonItems.map(item => item)) //["a", "e", "d"]

function getCommonItemsInArrays(array1,array2){
  return array1.filter(n => array2.indexOf(n) >= 0)
}

这似乎工作正常,但我想知道是否有办法通过sort 处理这个问题?

【问题讨论】:

  • “我知道如何按升序/降序排序” - 你确定吗?排序回调不应该返回布尔值......无论如何,data 项目是否保证在 sortBy 数组中?

标签: javascript arrays sorting ecmascript-6


【解决方案1】:

你的.sort() 回调可以做它需要做的任何事情来确定任何给定项目是否应该在任何其他给定项目之前或之后。因此它可以在您的 sortBy 数组中查找当前项目的索引并进行相应处理:

const sortBy = ['b','a','c','e','d']
const data = ['a','d','e']

console.log( data.sort((a,b) => sortBy.indexOf(a) - sortBy.indexOf(b)) )

在排序过程中多次调用.indexOf() 会有点低效,因此您可能希望在开始之前将sortBy 转换为对象:

const sortBy = ['b','a','c','e','d']
const data = ['a','d','e']

const sortByObject = sortBy.reduce((a,c,i) => {
  a[c] = i
  return a
}, {})

console.log( data.sort((a,b) => sortByObject[a] - sortByObject[b]) )

(请注意,排序回调不应返回布尔值。)

【讨论】:

  • 我认为这是一个非常人为的例子。你的解决方案有点工作:你传入一个不在列表中的值,比如['t','a','d','p','e']。您的代码返回 ["t", "a","e","d"]。如果你传入 ["t","a","d","p","e"],你会得到同样的结果!
  • 没有排序顺序是 a,e,d 所以初始测试没问题,
  • @RobertMoskal - 如果被排序的数组包含不在sortBy 数组中的值,那么我应该按照定义认为排序的结果是未定义的,但结果仍然会有相同的数字数组中的项目。但正如我在第一句话中所说,您将编写排序回调代码以执行排序规则所需的任何操作。 OP 没有说明如何处理不在 sortBy 中的值,但您可以添加一个 if/else 或任何默认值返回到未知值的字母排序。
  • 我没有大的批评。这是一个奇怪的场景,
猜你喜欢
  • 2014-08-17
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-04
  • 2016-11-01
相关资源
最近更新 更多