javascript - 按属性对对象数组进行排序以匹配提供的列表

标签 javascript arrays sorting

给定一个对象数组和一个值列表,我想有效地对对象进行排序,以便唯一属性(例如 key)的值遵循列表中值的顺序。

所以对于一个数组:

const users = [
  { key: 'A', name: 'Alice' },
  { key: 'B', name: 'Bob' },
  { key: 'C', name: 'Charlie' },
]

我希望函数的行为如下:

sortByList(['A', 'B', 'C'], users)
// -> Objects for Alice, Bob, Charlie

sortByList(['C', 'B', 'A'], users)
// -> Objects for Charlie, Bob, Alice

sortByList(['A', 'C', 'B'], users)
// -> Objects for Alice, Charlie, Bob

我想出了一个实现,它在数组上使用 Array::sort,然后在列表中使用 Array::indexOf

const users = [
  { key: 'A', name: 'Alice' },
  { key: 'B', name: 'Bob' },
  { key: 'C', name: 'Charlie' },
]

const sortByList = (list, arr) => arr.sort(
  (a, b) => list.indexOf(a.key) - list.indexOf(b.key)
);

sortByList(['C', 'B', 'A'], users)

console.log(users)

但我觉得这不是一个有效的解决方案。时间复杂度为 O(N^2*log(N)) ,相当高。有没有更好的?

我不关心就地排序或稳定性,想象一下数组有几十到几百个项目。

最佳答案

有了限制,你可以保证keys-list绝对等于用户数据中的keys,你可以避免任何排序并创建一个临时映射,以生成一个新的“排序”数组:

const users = [
  { key: 'A', name: 'Alice' },
  { key: 'B', name: 'Bob' },
  { key: 'C', name: 'Charlie' }
]

const orderList = ['A','B','C']

const sortByList = (list, arr) => {
   const tmpMap = arr.reduce((acc, item) => {
      acc[item.key] = item
      return acc
   }, {});

   return list.map((key) => tmpMap[key])
}

console.log(
  sortByList(orderList, users)
)

关于javascript - 按属性对对象数组进行排序以匹配提供的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65993915/

相关文章:

javascript - qooxdoo 中的离线商店是否与所有浏览器和本地文件系统兼容?

C++:根据 struct 的整数之一对 vector <struct>(其中 struct 有 2 个整数)进行排序

java - 似乎无法弄清楚在java中对对象数组进行排序

java - 使用 ECollections 进行扩展排序

javascript - 如何在页面加载后通过 jQuery 动态插入 &lt;script&gt; 标签?

javascript - 关于使用外部 Dom 按钮在 Highcharts.js 中向下和向上钻取的问题

javascript - 如何将多维数组转换为二维数组?

arrays - 创建 NumPy 数组时无法理解数据类型

javascript - Jquery Tmpl If 语句不起作用

c# - 如何获取多维数组的宽和高?