【问题标题】:Sort Object (string) by another object按另一个对象排序对象(字符串)
【发布时间】:2023-03-13 07:47:01
【问题描述】:

我目前有一个如下所示的对象:

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

它的目的是检查是否键a/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"
};

【问题讨论】:

  • 预期的输出究竟是什么?
  • @Akrion,只是在foreach之前的预期结果中添加了
  • 不清楚你想要什么,但你可能应该在某个地方.split("/")

标签: javascript arrays sorting object


【解决方案1】:

您可以尝试以下方法来处理您的场景

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

var sort = {
    "a": ["something", "somethingdifferent", "somethingelse"],
    "b": ["somethingess", "somethingdifferentasdasd"]
}

let tmpData = {}
for(let [key, value] of Object.entries(data)) {
  tmpData[key.split('/')[0]] = tmpData[key.split('/')[0]] || {}
  tmpData[key.split('/')[0]][key.split('/')[2]] = { [key]: value, value: 999 }
}

let tmpResult = {}
for(let [key, args] of Object.entries(sort)) {
  args.forEach((d,i) => tmpData[key][d]['value'] = i)
  
  Object.assign(tmpResult, ... Object.entries(tmpData[key]).map(([, v]) => v).sort((a, b) => a.value - b.value))
}

let {value, ...result} = tmpResult
console.log(result)

【讨论】:

    【解决方案2】:

    你可以这样做:

    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 props order is not guaranteed

    对象是对象类型的成员。它是一个无序的 属性集合,每个属性都包含一个原始值, 对象或功能。存储在对象属性中的函数是 称为方法。

    虽然 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)

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

    【讨论】:

    • 谢谢,问题,你在哪里引用排序对象?它是如何知道如何排序的
    • 对不起,从您的问题来看,您会使用第一个 data 并使用 [0]/[1]/[2] 索引对其进行排序。因此,这会从data 获取输入,并通过仅比较[0]/[2] 索引来获取键对它们进行排序。如果这不正确,请告诉我。
    • 对不起Akrion,我想我可能把大家弄糊涂了。 var sort 应该是我的排序应该基于的,背后的想法是我目前有 "a" 对象,它有一个应该如何排序的数组。但是,要将其拆分,您需要 [0][2]
    • 更新了答案
    【解决方案3】:

    javascript 中的对象未排序,因此您无法对键进行排序。但是,假设您希望得到一个排序后的键数组...

    const inputData = {
      "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 sortingFunction = (x, y) => {
      let [a, b, c] = x.split('/');
      let [A, B, C] = y.split('/');
      if (a < A) {
        return -1;
      } else if (A < a) {
        return 1;
      } else {
        if (c < C) {
          return -1;
        } else if (C < c) {
          return 1;
        } else {
          return 0;
        }
      }
    };
    
    const sortedKeys = Object.keys(inputData);
    sortedKeys.sort(sortingFunction);
    
    console.log(sortedKeys);

    【讨论】:

      猜你喜欢
      • 2021-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-08
      • 2014-07-10
      • 2020-05-24
      • 1970-01-01
      • 2013-01-02
      相关资源
      最近更新 更多