-1

I have an object ( array of hashes ) and I need to convert it into ordered key value pairs.

This is object:

var places_info = [
  {"place_id":180,"name":"Abc","city":"Gotham"},
  {"place_id":161,"name":"Def","city":"Sin City"},
  {"place_id":178,"name":"Ghi","city":"Timbuktu"},
  {"place_id":179,"name":"Jkl","city":"Acapulco"},
  {"place_id":174,"name":"Mno","city":"Desire"}
];

And I need function to return key/value (place_id/name) pairs in same (alphabetical by name) order:

{ 
  '180': 'Abc', 
  '161': 'Def',
  '178': 'Ghi',
  '179': 'Jkl',
  '174': 'Mno'
}

Actual use: I need it as input for Jeditable Select-input (actual example on demo page). Select-type needs for data-property key/value pairs or function which returns them. So far I got select options in random order, but--as you may imagine--I need them ordered by value....

As for Jeditable the data may be just a fake hash (string formed as JSON key/value pairs), my only solution is like this:

var arr = new Array;
for ( i in places_info ) {
  arr.push( "'" + places_info[i].place_id + "':'"  +  places_info[i].name + "'" );
}
var uglyString = '{' + arr.join(',') + '}';

Is there some more elegant and intuitive approach for such goal? I'd like to keep my data in proper data structure. Converting it to flat string seems like hack.

Edit

I must reconsider the problem. I did not test Jeditable with generated string and seems it evals string into hash and then my desired order is gone. So, this problem needs different approach. Maybe I need make my own datatype for Jeditable. But this seems like different question.

w.k
  • 8,038
  • 4
  • 27
  • 50
  • Since javascript doesn't guarantee you the order of the key in an Object, I think you have no other choice. I hope, this post might help you a bit http://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – Rudra Aug 09 '15 at 08:16

2 Answers2

2

Until ES6, there is NO guaranteed order for properties on a Javascript object. They are unordered. If you need order and need to support environments before ES6, then you can't just use properties on an object and get a guaranteed order of those properties.

So your choice is to pick some other data structure that can reliably express order. Collapsing it all down to a string like you've done is one choice, though that means it has to be re-parsed in order to be useful to Javascript. It would be better to keep it in some natively accessible Javascript format. For order, that means using an array.


You can return ordered pairs by returning an array for the ordering and then there are several choices for what to put in the array. Here are several examples of ordered key/value pairs:

// array of objects
var a = [{key: "greeting", value: "hello"}, {key: "salutation", value: "welcome"}];

Since that seems a little verbose to me, I often use a shortcut that just knows that every other element is a key, then value, then key, then value and doesn't have to spell out those property names over and over:

// alternating key/value
var a = ["greeting", "hello", "salutation", "welcome"];

Or, you could put each ordered pair in an array itself so each sub-array is an ordered pair:

// sub-arrays
var a = [["greeting", "hello"], ["salutation", "welcome"]];
jfriend00
  • 580,699
  • 78
  • 809
  • 825
  • Jeditable data-property needs key/value pairs, I can't use arrays. – w.k Aug 09 '15 at 08:19
  • @w.k - if you want to control the order in Javascript, you use arrays. You don't easily manipulate the order of properties on an object. In fact, until ES6, there is NO guaranteed order of properties on an object. So, because you said you wanted order, I suggested an array - that's what Javascript uses for order. If you could use a string (yuk), then why can't you use an array? I don't understand. I just thought you were trying to find an organized way to store ordered key/value pairs. – jfriend00 Aug 09 '15 at 08:21
  • I think you are right, because even using the string does not work as I expected. See my edit. Thank you! – w.k Aug 09 '15 at 10:08
0

The properties order in objects are not guaranted in JavaScript, you need to use an Array.

Take a look at this:

var obj = {
   '180': 'Abc', 
   '161': 'Def',
   '178': 'Ghi',
   '179': 'Jkl',
   '174': 'Mno'
};
for (var i in obj) { console.log(i); };

will give you: 161, 174, 178, 179, 180

biancamihai
  • 951
  • 6
  • 14