我需要创建一个对象,其中键是由数字组成的字符串,但是我无法以正确的方式对其进行排序:
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”放到最后。
答案 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)
}