javascript - 按属性对对象数组进行排序以匹配提供的列表
问题描述
给定一个对象数组和一个值列表,我想有效地对对象进行排序,以便唯一属性(比如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)) ,相当高。有更好的吗?
我不关心就地排序或稳定性,想象数组有几十到几百个项目。
解决方案
有了限制,您可以保证键列表绝对等于用户数据中的键,您可以避免任何排序并创建一个临时映射,以生成一个新的“排序”数组:
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)
)
推荐阅读
- compiler-errors - 当我在方法签名中使用 hyper::Client 时,为什么会收到错误“类型参数数量错误”?
- asynchronous - 如何让 Vue 子组件识别 axios 在 Vue $root 组件上完成加载?
- mysql - 在 Express App pug div 类中重复 MySQL 数据
- c++ - 错误解密错误 OpenSSL C++ & QT AES 256 CBC
- asp.net-mvc - ASP.NET MVC 表单中视图中的空对象
- javascript - 在 PHP 中使用 Ajax 在数据库中插入数据
- python - scikit-learn 中的 fit 函数如何进行验证?
- sql - 使用 SQL 从 XML 数组中提取数据
- javascript - 在 javascript 模板文字中使用条件
- variables - Terraform 模块 - 变量和 .tfvars