javascript - 按另一个对象排序对象(字符串)
问题描述
我目前有一个看起来像这样的对象:
var data = {
"a/a/something": "something/ehere"
"a/b/somethingelse": "something/else/here",
"a/b/somethingdifferent": "something/else/different",
"a/c/somethingess": "something/else/somethingess",
"b/a/somethingess": "something/else/somethingess",
"b/a/somethingdifferent": "something/else/somethingess",
"b/b/somethingdifferentasdasd": "something/else/somethingdifferent",
};
这Object.keys
目前由 3 个元素分割,我只关心第一个和第三个[1]/[2]/[3]
。
我目前正在运行一个foreach
遍历所有对象键的循环,但我想按标准 1 和标准 3 对其进行排序。
我的循环:
Object.keys(data).forEach((dataID) => {
register(dataID);
});
我的排序:
var sort = {
"a": ["something", "somethingdifferent", "somethingelse"],
"b": ["somethingess", "somethingdifferentasdasd"]
}
目标是它会检查是否 keya/a/something
以及当它到达循环时,它应该在它到达 foreach 之前检查排序对象。
forEach 之前的预期结果
var data = {
"a/a/something": "something/ehere"
"a/b/somethingdifferent": "something/else/different",
"a/b/somethingelse": "something/else/here",
"a/c/somethingess": "something/else/somethingess",
"b/a/somethingess": "something/else/somethingess",
"b/b/somethingdifferentasdasd": "something/else/somethingdifferent",
"b/a/somethingdifferent": "something/else/somethingess"
};
解决方案
你可以这样做:
const data = { "a/a/something": "something/ehere", "a/b/somethingelse": "something/else/here", "a/b/somethingdifferent": "something/else/different", "a/c/somethingess": "something/else/somethingess", "b/a/somethingess": "something/else/somethingess", "b/a/somethingdifferent": "something/else/somethingess", "b/b/somethingdifferentasdasd": "something/else/somethingdifferent", };
const sort = { "a": ["something", "somethingdifferent", "somethingelse"], "b": ["somethingess", "somethingdifferentasdasd"] }
const splitter = (s) => {
let arr = s.split('/'), index = sort[arr[0]].indexOf(arr[2])
return ({ k: arr[0], v: index < 0 ? Number.MAX_SAFE_INTEGER : index})
}
const sorter = (a, b) => splitter(a).v - splitter(b).v
const result = Object.entries(
Object.keys(data)
.reduce((r, c) => (r[splitter(c).k] = [...r[splitter(c).k] || [], c], r), {})
)
.map(([k, v]) => v.sort(sorter))
.reduce((r, c) => r.concat(c))
.reduce((r, c) => Object.assign(r, ({ [c]: data[c]})), {})
console.log(result)
Object.keys
这个想法是通过索引获取键,然后对它们进行分组[0]
,对它们进行排序,然后组成最终对象。
注意: 不保证对象道具顺序:
对象是 Object 类型的成员。它是一个无序的属性集合,每个属性都包含一个原始值、对象或函数。存储在对象属性中的函数称为方法。
尽管 SO 控制台会在 Chrome 控制台中显示所需的顺序,但您不会得到相同的输出。仅供参考。
所以考虑到这一点,如果你替换最后一行而不是reduce
你这样map
做,最终结果是一个数组:
const data = { "a/a/something": "something/ehere", "a/b/somethingelse": "something/else/here", "a/b/somethingdifferent": "something/else/different", "a/c/somethingess": "something/else/somethingess", "b/a/somethingess": "something/else/somethingess", "b/a/somethingdifferent": "something/else/somethingess", "b/b/somethingdifferentasdasd": "something/else/somethingdifferent", };
const sort = { "a": ["something", "somethingdifferent", "somethingelse"], "b": ["somethingess", "somethingdifferentasdasd"] }
const splitter = (s) => {
let arr = s.split('/'), index = sort[arr[0]].indexOf(arr[2])
return ({ k: arr[0], v: index < 0 ? Number.MAX_SAFE_INTEGER : index})
}
const sorter = (a, b) => splitter(a).v - splitter(b).v
const result = Object.entries(
Object.keys(data)
.reduce((r, c) => (r[splitter(c).k] = [...r[splitter(c).k] || [], c], r), {})
)
.map(([k, v]) => v.sort(sorter))
.reduce((r, c) => r.concat(c))
.map(x => ({[x] : data[x]}))
console.log(result)
您将获得有保证的索引顺序和正确/推荐的输出。您不能依赖对象道具顺序。
推荐阅读
- python-3.x - 如何使用python正确更新firestore中的地图字段?
- java - 为什么我的java程序在eclipse上成功时没有从命令行连接到oracle?
- r - 如何合并/合并数据框中的两列并创建一个指定数据点来源的新列?
- angular - Angular removeAt 总是从 FormArray 中删除最后一个元素
- reactjs - 打字稿文件中的 prettier-eslint 运行两次并且与 eslint 规则有冲突
- linux - v4l2_ioctl 和 ioctl 的区别
- r - 在 .Rmd 文档中使用 JuliaCall 和 knitr 抑制 Julia 输出时添加提示
- android - Android 应用内购买按需下载?
- java - Java - 转换类
- huawei-mobile-services - HMS Core SDK更新至5.0.4.300及以上版本时,无弹窗提示用户安装或更新HMS Core(APK),结果码90