javascriptjeditable

How to return ordered key/value pairs from function?


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.


Solution

  • 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"]];