【问题标题】:guaranteed indexed object to array in order保证索引对象按顺序排列
【发布时间】:2019-03-21 23:03:31
【问题描述】:

this question的扩展名

所以我正在玩一个项目,我发现自己需要创建一个字符串,其中我不知道刻字的确切顺序,但我确实知道它们的位置(并且通过扩展,这个长度字符串)。

这样做的部分原因是我不想在此过程中的任何时候跳过数组元素(NO ["a", , "t"] during the process)。这意味着插入的顺序很重要。

let string_length = 10;

let o = {
  0: "a",
  4: "q",
  7: "t",
  3: "p",
  6: "h",
  1: "z",
  2: "t",
  5: "a",
  9: "b",
  8: "z"
};

function obj_to_arr(o) {
  // this returns ["a","z","t","p","q","a","h","t","z","b"]
}

到目前为止我找到的所有答案都不一定保证给定一个索引对象,它会给出相应的有序对象,这主要是因为对象的性质,是无序的。

有没有办法实现这个?

【问题讨论】:

  • Stack Overflow 通常更喜欢问题而不是陈述 ;-)
  • 呼应一下……实际的问题是什么?
  • 你的意思是内置的Object.keys()Object.entries()函数?
  • 如果插入顺序很重要,那么您在这里绝对使用了错误的数据结构。仅当您不关心键值顺序时才使用对象,因为规范确实 no 保证即使存在 is 顺序。这完全由 JIT 决定。一旦let o 存储在内存中,这些键就没有义务反映您写下的顺序,并且实际上很可能以排序方式存储,以便对象上的属性查找可以使用有效的解析算法。
  • 元组是应该“保持在一起”的任何事物集合的通用名称,因此在这种情况下,您需要像 let properlist = [ {key: 0, value: a, {key: 4, value: q}, ...] 这样的东西,现在您可以依赖于这样一个事实,即在您迭代时,键和值将始终具有相同的顺序。

标签: javascript arrays sorting object


【解决方案1】:

您可以通过两种可能的方式(可能还有更多方式)解决此问题。

数组

要么将包含键和值的对象添加到数组中。

array.push({c: "a"})array.push({ key: c, value: "a"}),然后添加下一个,依此类推。

Push 将一个元素放在数组的末尾。

排序对象

或者您使用字母键插入对象,在这种情况下,您可以使用下面的示例。

您可以对对象的键(属性)进行排序,并使用它们来访问每个值并将它们放入另一个数组中。这是一个详细的示例,说明如何做到这一点。

const someObject = {
  c: "a",
  4: "q",
  7: "t",
  b: "p",
  6: "h",
  1: "z",
  2: "t",
  5: "a",
  a: "b",
  8: "z"
};


function obj_to_arr(obj) {
  let result = []
  
  // Get keys from object as an array
  let keys = Object.keys(obj)
  console.log('keys: ', keys)
  
  // Sort the array in alphabetical order
  let sorted = keys.sort()
  console.log('sorted: ', sorted)
  
  // Add each value to the resulting array
  sorted.forEach(function(key) {
    console.log('adding ' + obj[key] + ' to array')
    result.push(obj[key])
  })

  console.log('result: ', result)
  return result
}

// Call the function
obj_to_arr(someObject)

【讨论】:

  • 正如已经建议 Object.keys() 的其他答案一样,该函数保证键的顺序与声明的顺序相同。
  • 因为您没有阅读帖子:他们想要他们声明的顺序,根本不是按字母数字排序的。键和值都不遵循标准顺序。
  • 注意,我编辑了我的答案以实际回答问题。感谢您的评论。
  • 请注意,Array.prototype.sort() 的默认字典排序意味着键“10”在键“2”之前
  • 非常正确。在这种情况下,您可以使用自定义 sorting function
【解决方案2】:

使用Object.keys(),您可以检索一个键数组,sort 以数字方式检索它们,然后map 将排序后的数组与值合二为一。

结果将是一个值数组,其顺序与键的数值相对应,即使它们不是连续的。

例如

let o = {"0":"a","1":"z","2":"t","3":"p","4":"q","5":"a","6":"h","7":"t","8":"z","10":"b"}

let sortedValues = Object.keys(o)
    .sort((a, b) => a - b)  // numeric comparison
    .map(k => o[k])         // map to values

console.info(sortedValues)

【讨论】:

  • 但是,Object.keys 不保证在 JIT 将对象提交到内存时不会重新排序键。在这种情况下,排序不会恢复原来的顺序。
  • @Mike'Pomax'Kamermans 我的印象是 OP 想要按数字顺序排列的键。这就是我对它们进行排序的原因。这在我想要的输出中似乎很清楚
【解决方案3】:

由于 Javascript 规范,简短的回答是“你不能”。

不保证 Javascript 中的对象以任何方式对其键进行排序,因为它是允许引擎优化的原始类型,包括重新排序键以加快属性访问。

如果排序真的很重要,那么您不应该使用对象原语。一个元组数组(有保证的顺序):

let fixedList = [
  { key: 0, value: 'a' },
  { key: 4, vlaue: 'q' },
  ...
];

或者您可以使用Map,它具体地存在作为拥有“一个对象,与您声明的键/值对的顺序相同”的一种方式。

在这两者中,对于数据传输,您可能需要前者,而对于运行代码,您通常需要后者。

【讨论】:

  • 原始顺序无关紧要。这才是重点。 o 将以我不知道的某种顺序生成,当长度达到 10 或 string_length 时,我运行将对其进行排序的函数。创建新数组时,插入顺序很重要。
  • 它会如何如何?不是“使用什么代码”,而是“在将内容插入固定排序数组之前,您需要进行什么排序”?
  • 这就是为什么我要问它是否可以实现,从我得到的似乎不可能
  • 如果 what 可以实现呢?因为您的帖子询问对象中指定的顺序,所以如果您想要该顺序,那么这个答案是 only 答案:它不能完成,因为没有 is对象键的排序。 Javascripts 中的对象字面量没有有序键,因此没有顺序可找到:没有。当然,如果这不是您要问的,那么请编辑您的问题,我可以相应地编辑我的回答。
  • 我很抱歉造成混乱,但我很确定问题问的是什么,我想说的是:给定一个无序的索引对象,你如何(如果可能的话)做到这一点进入和数组而不跳过值
猜你喜欢
  • 2021-01-07
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 2013-08-29
相关资源
最近更新 更多