如何对键为数字字符串的数组进行排序

时间:2019-11-07 17:39:12

标签: javascript

我需要创建一个对象,其中键是由数字组成的字符串,但是我无法以正确的方式对其进行排序:

let simple_arr = ['00', '11', '22', '33'];
let simple_obj = {};

for (let it of simple_arr) {
  simple_obj[it] = "anything";
}

for (let it2 in simple_obj) { 
  console.log(it2)
}

我想要的输出是:00、11、22、33。

但是它复制了:11、22、33、00。

我已经尝试使用Object.keys对该对象进行排序,但是总是在对它设置迭代器时,将值“ 00”放到最后。

3 个答案:

答案 0 :(得分:4)

您不能使用for-in循环来依赖您说过的输出。尽管对象属性从ES2015开始具有顺序,但for-in循环不要。 (来自Object.keys的数组也没有。)

如果要订购,则需要一个数组。 (但是在某些情况下,您也可以使用Map;请参见下文。)

此外,即使使用ES2015的属性顺序,显示的键也将永远不会显示顺序,因为'00''11''22''33':不是canonical number String。 ES2015顺序(用于支持该顺序的操作)是属性,其名称是规范数字字符串格式的字符串,按数字顺序,其次是按添加顺序按其他字符串命名的属性,然后是按符号命名的属性。

因此,您的对象将永远不会像您所说的那样表现。使用数组。

(当然,如果引入前缀,那么它们都不是规范数字字符串格式,并按所需顺序添加属性,则可以与Object.getOwnPropertyNames和支持该顺序的其他操作一起使用。但是我真的不会那样做。)

另一种选择是使用Map,它与对象始终不同,它遵循首次使用键的顺序。¹如果您这样创建Map,则: / p>

const map = new Map(simple_arr.map(key => [key, "anything"]));

...然后遍历该映射将可靠地访问'00'条目,然后依次访问'11'条目,然后'22'条目和'33'条目:< / p>

const simple_arr = ['00', '11', '22', '33'];
const map = new Map(simple_arr.map(key => [key, "anything"]));
for (const [key, value] of map.entries()) {
    console.log(key, value);
}


¹这是简单的版本。较长的版本:如果您向地图添加键/值,而该键尚未在地图中,则它将位于地图键列表的末尾。如果您为该键设置新值,则该值不会在该列表中移动。如果您删除密钥,然后稍后再添加,它将再次结束。

答案 1 :(得分:3)

对象在键方面没有排序的概念。即使您可以使用特定浏览器中的特定数据集来实现此目的,也不能保证密钥会按您想要的顺序出现。

如果您确实想实现此目的,则应该对Object.keys()返回的键进行排序,并对其进行迭代。


我上面的原始答案不正确。 As of ES2015,对象键确实具有特定的顺序。我仍然坚持认为,依靠对象的键顺序可能不是一个好主意-使用Map保留键的原始值(不将其强制转换为字符串),而是在迭代时对键进行排序。

答案 2 :(得分:1)

由于ES2015对象键确实具有traversal order

  • 有效数字(整数索引)的字符串排在最前面,并按其值排序
  • 未放置在数字字符串后面的字符串,其顺序由输入顺序定义

00转换为0,以便按数字值对其进行排序:

const simple_arr = ['0', '11', '22', '33'];
const simple_obj = {};
for(let it of simple_arr){
  simple_obj[it] = "anything";
}

for(let it2 in simple_obj){ 
  console.log(it2)
}