首页 > 解决方案 > 按另一个对象排序对象(字符串)

问题描述

我目前有一个看起来像这样的对象:

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"
};

标签: javascriptarrayssortingobject

解决方案


你可以这样做:

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)

您将获得有保证的索引顺序和正确/推荐的输出。您不能依赖对象道具顺序。


推荐阅读