-4

How can I create an associative array that guarantees order?

Object (not guarantee order):

var obj = {
  "first":"first",
  "2":"2",
  "34":"34",
  "1":"1",
  "second":"second"
};
for (var i in obj) {
    console.log(i);
};

Result:

1
2
34
first
second

Array:

var a = new Array();
a['first'] = "first";
a['2'] = "2";
a['34'] = "34";
a['1'] = "1";
a['second'] = "second";
console.log(a); // [1: "1", 2: "2", 34: "34", first: "first", second: "second"]

for (var i in a) {
    console.log(i);
};

Result:

1
2
34
first
second

The array does not guarantee order at all.

How can I create a correct array that guarantees order then?

Community
  • 1
  • 1
laukok
  • 47,545
  • 146
  • 388
  • 689
  • What do you mean by "guarantees order"? *What* order? – Pointy Jun 29 '16 at 14:45
  • 2
    Possible duplicate of [How to iterate javascript object properties in the order they were written](http://stackoverflow.com/questions/2647201/how-to-iterate-javascript-object-properties-in-the-order-they-were-written) – JJJ Jun 29 '16 at 14:47
  • 1
    You might want to look at the [Map object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map). This should allow for ordering – neilsimp1 Jun 29 '16 at 14:52
  • 3
    Your "array" indices are actually ordinary object properties accessed using the bracket notation. Use a `new Map()` which keeps the insertion order of key-value pairs. – le_m Jun 29 '16 at 14:52
  • Property key order with objects is a [broad subject](http://stackoverflow.com/a/32149345/6445533) –  Jun 29 '16 at 14:55
  • 2
    *"The array does not guarantee order at all."* Not the way you use it. If you do `a.length` you would see that there are no elements in your array. Only certain numeric properties are considered to be elements of an array. The order is guaranteed implicitly by the natural order of numeric indexes. – Felix Kling Jun 29 '16 at 15:24
  • @FelixKling `Not the way you use it.` - how can I use it correctly then? Can u give an example please? – laukok Jun 29 '16 at 15:31
  • `var a = ["first", "2", "34"];`, but that doesn't necessarily solve your problem. Arrays are not meant to have arbitrary string properties. – Felix Kling Jun 29 '16 at 15:33

2 Answers2

2

In ECMAScript 6 Map type is an ordered list of key-value pairs, where both the key and the value can have any type. A Map object iterates its elements in insertion order.

The forEach method executes a provided function once per each key/value pair in the Map object, in insertion order.

var a = new Map;
a.set("first", "first");
a.set("2", "2");
a.set("34", "34");
a.set("1", "1");
a.set("second", "second");

a.forEach(function(value, key) {
  console.log(key + ' => ' + value)
})

You can also use for...of loop and it returns an array of [key, value] for each iteration.

var a = new Map;
a.set("first", "first");
a.set("2", "2");
a.set("34", "34");
a.set("1", "1");
a.set("second", "second");

for (var p of a) console.log(p)
Nenad Vracar
  • 102,378
  • 14
  • 116
  • 136
0

You cannot save properties in a specific order in object, but you can parse it while printing in any custom order. You will have to create another array of values or if to be printed on document, then an HTML string.

You can try something like this:

Note: You can check using comparison operator > or <. You can parse numeric values and compare or string compare non-numeric values, but will give issues if you have something like eleven.

var obj = {
  "first":"first",
  "2":"2",
  "34":"34",
  "1":"1",
  "second":"second"
};

var sortOrder = ["1", "2", "34", "first", "second"];

var html = Object.keys(obj).sort(function(a,b){
  var _a = getSortPosition(a);
  var _b = getSortPosition(b);
  return _a> _b ? 1: _a<_b ? -1 : 0;
}).map(function(item){
  return "<span>" +item+ "</span>";
}).join("<br/>");

document.getElementById("content").innerHTML = html;

function getSortPosition(key){
  var _index = sortOrder.indexOf(key);
  return _index >-1 ? _index : 999;
}
<div id="content"></div>
Rajesh
  • 21,405
  • 5
  • 35
  • 66
  • @Downvoter please comment. I might be wrong and would like to learn from it – Rajesh Jun 29 '16 at 15:12
  • I think this is the right approach. Even with modern Map instances, all that's guaranteed is insertion order. That's useful, perhaps, in limited cases, but if a *durable* ordering based on the nature of the keys is needed then maintaining that explicitly is the only robust approach. – Pointy Jun 29 '16 at 15:15
  • String comparison will limit the options. – Rajesh Jun 29 '16 at 15:19