-1

I'm trying to convert an object to list of key-value pairs using Object.entries and then i loop each of the entry, everything is fine except the order of result is different with the object i give when then the key is like "06" or "01" or else that start with "0"

This is tested on NodeJs V10.16.0, UTF-8 character set.

const obj1 = {
  '01': "val1",
  "06": "val6",
  "13": "val13",
  "88": "val88",
  "100": "val100"
}

Object.entries(obj1).forEach(([k, v]) => {
  console.log(k + "-" + v)
})

The result of code above will be :

13-val13
88-val88
100-val100
01-val1
06-val6

I expect the output to be the in the same order as the object i give,like following:

01-val1
06-val6
13-val13
88-val88
100-val100

This thing only happen when the property key in the object start with "0" another type of property is just fine so far. Please help what is it actually?

Barmar
  • 741,623
  • 53
  • 500
  • 612
rizesky
  • 424
  • 6
  • 13
  • 5
    Objects aren't required to maintain the order of properties. – Barmar Sep 23 '19 at 15:56
  • 5
    This is not a bug. The official spec of javascript does not specify key ordering of objects – TKoL Sep 23 '19 at 15:56
  • Use a [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) if you want to maintain insertion order. – Patrick Roberts Sep 23 '19 at 15:58
  • In general, use an array when order is important. – Barmar Sep 23 '19 at 15:58
  • @TkoL What i mean is why the object entries itself do some sorting behind? – rizesky Sep 23 '19 at 15:59
  • @Rizesky the order of iteration is up to the implementation. You can consider it semi-random. – Hubert Grzeskowiak Sep 23 '19 at 16:00
  • if the order is supposed to be ascending order of numeric keys, then convert to array and sort the array based on the numeric keys – Nithin Kumar Biliya Sep 23 '19 at 16:00
  • @PatrickRoberts i dont want to maintain the insertion order, and i dont want to change anything about the order, but the javascript api (Object.entries) itself change the order of my object. Why it happen? – rizesky Sep 23 '19 at 16:01
  • The underlaying datastructure is probably a hashtable of some sort. It's optimized for lookup speed - does not maintain the insert order. – HaukurHaf Sep 23 '19 at 16:01
  • @NithinKumarBiliya i dont want to do an ordering or sorting, my problem is the javascript itself do some ordering to my object that i dont want. Why it happen? – rizesky Sep 23 '19 at 16:03
  • 1
    @HaukurHaf but if the property key in the object is not start with "0" the result will be fine, the order of what i give in object will be the same in result. – rizesky Sep 23 '19 at 16:04
  • @HubertGrzeskowiak what i mean is why the javascript do an ordering that i dont ask for? – rizesky Sep 23 '19 at 16:06
  • @Rizesky, it's because of how the data-structure for objects is implemented. Read the comments/answers. You cannot use an object if you have to rely on maintaining the insertion order. Use a map or an array instead. – HaukurHaf Sep 23 '19 at 16:07
  • @Rizesky it's ordering the entries as much as you order your coins within your purse. It's coming out semi-randomly, maybe with the heavier coins first, maybe with the rounder ones first, maybe it's completely random - you can not know, because it's not part of the contract. – Hubert Grzeskowiak Sep 23 '19 at 16:08
  • the JS spec does not guarantee ordering. The ordering is left to JS implementers. Different browsers do it differently - [ref this ans](https://stackoverflow.com/a/280861/1298824) – Nithin Kumar Biliya Sep 23 '19 at 16:08
  • Possible duplicate of [Does JavaScript Guarantee Object Property Order?](https://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order) – Hubert Grzeskowiak Sep 23 '19 at 16:09
  • 1
    @Rizesky `i dont want to maintain the insertion order`, you clearly _do_, based on your expected output. – Patrick Roberts Sep 23 '19 at 16:09
  • We should note that the order CAN be printed identically as you specify it, but that is (for all relevant purposes) absolute coincidence. It's almost like rolling a dice, having the same number all times, and assuming that the dice always shows just that one number. – Hubert Grzeskowiak Sep 23 '19 at 16:21

2 Answers2

2

As stated in the comments, objects are not required to iterate properties in insertion order. If you require the iteration order to match the insertion order, use a Map instead:

const map1 = new Map([
  ['01', "val1"],
  ["06", "val6"],
  ["13", "val13"],
  ["88", "val88"],
  ["100", "val100"]
]);

for (const [k, v] of map1) {
  console.log(k + "-" + v);
}
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
1

An JavaScript Object is an unsorted key-value store, a.k.a. an Associative Array. This is comparable to Java's Maps or Python's dicts. There is absolutely no guarantees of any order when fetching or iterating over the keys, values or key-value pairs. Any order you may see is due to the internal implementation and can not be relied on. You may not even rely on it being deterministic.

These objects are equivalent:

const obj1 = {
  '01': "val1",
  "06": "val6",
  "13": "val13",
  "88": "val88",
  "100": "val100"
}
const obj2 = {
  "100": "val100",
  "06": "val6",
  "13": "val13",
  "88": "val88",
  '01': "val1"
}

For sorted entries, use Map or or Array.

Hubert Grzeskowiak
  • 15,137
  • 5
  • 57
  • 74
  • https://repl.it/@RizeskySiallaga/js-example can you please check this link? please check obj2, the order of the result is always the same as the object i give to it – rizesky Sep 23 '19 at 16:15
  • @Rizesky [I'm not so sure about that](https://repl.it/repls/LavenderTinyDatawarehouse). – Patrick Roberts Sep 23 '19 at 16:16