jquery - value - sort json object by key




How do you stop Chrome and Opera sorting JSON objects by Index ASC? (11)

Changing integer to string didn't work for me (Chrome, jQuery 1.7.1). So to keep the order (yes, it's object abusing), I changed this:

optionValues0 = {"4321": "option 1", "1234": "option 2"};

to this

optionValues0 = {"1": {id: "4321", value: "option 1"}, "2": {id: "1234", value: "option 2"}};

I've got a problem.

Using ajax I sent a correctly formed JSON object using:

            $.ajax({
                type: "POST", 
                url: SITE_URL+'/data.php',
                dataType: "json",
                data: { ajax: 1 },
                success: function(data) {
                    console.log(data);
                }
            });

However, Opera and Chrome, although receiving the same object, print out the object in an incorrect order, it seems like they both perform a sort by ID number instead of just leaving it alone!

Is there a way to stop this auto sort?

Edit, after finding out it is a sort by index number I'm thinking the best method might be to not use the index for storing the object_id and instead store the id number which I want to order the object by.

However I would still like to know if there is a way to stop the sort.

Thank you

Edit2, I'll just like to note that I'm going to work on a different way of doing this, as I feel like I'm abusing objects with this method. However I'd still like to understand why Opera and Chrome feel it is their right to change the order of my objects IDs:

The problem would be me trying to save processing power, lets say we have people with an ID,

1.John, 2.Frank and 3.Sally. However each of these people have a hight property set (and other things). 1.John.180, 2.Frank.220, 3.Sally.150. To save on processing, my I request the result of people be sorted by their height so I get an array of 2, 1, 3 with their other properties. I JSON this array and send it to the browser.

Now FF will keep the new order People[1] would still be John but in a For n as person loop they'll be out of order.

If I can't get around this I'll just have to not bother sorting at the SQL stage and add extra looping and sorting into an array in the JS stage although I wanted to avoid more stress on the browser as its already a Js heavy page.

Many thanks


Different browsers handle objects in different ways, my fault was to try and use the order I built an object as a reference where I shouldn't.


I had the same "problem" and did not want to go back and change too much in the code. Figured out that at least Google Chrome only re-sorts numeric indexes. As long as the index is considered a string it will show up in the "intended" order. Could someone please verify this on Opera?


I had the same issue and took me a while to work out what was even causing it, what a pain. I ended up removing ID from the index and used array_push, instead of being:

$section[$s_id]['Type'] = $booktype;

etc. I changed it to

array_push($sections, array('ID'=>$s_id, 
                            'CourseID'=>$courseid, 
                            'SectionName'=>$secname, 
                            'Order'=>$order, 
                            'Created'=>$created, 
                            'Description'=>$desc
                            ));

Which allowed me to keep the ordering from PHP since the new indexs where already in order (0,1,2,3 etc as opposed to 112, 56, 411 etc)


I resolved this problem using this code:

$('.edit_district').editable("/moderator/sale/edit_sale/", {
    data   : " {'_7':'10 street', '_9':'9 street', '_11':'park'}",
    type   : 'select',
    submit    : 'OK',
    onblur : 'submit'
});

and in script.php:

...
case "id_district":

$district = Districts::GetDistrictByID(Database::getInstance(), (int)substr($value,1));

if($district instanceof District){
    $data["id_district"] = $district->id_district;
    echo $district->title;
}

break;

...

Make your object identifier in the JSON string parameter, it works without automatic sorting.


One trick that can help is as follow:

You have to add "i" to key while you prepare your data in for loop, that made a trick. Works perfectly for each browsers.

for Example :

 for(var i=1;i<4;i++){

 data[''+i+''+your_random_generatedId+'']  = {"questionText":"","answer":"","options":"",noOfOptions:""};

 console.log(data[''+i+''+your_random_generatedId+'']); // This prints the log of each object inside data 

 }

 console.log(data); // This will print the Object without sorting

Hence your Object will be as follow:

Object {156674: Object, 201705: Object, 329709: Object}

hope this helps :)


Seems the best way is to avoid associative arrays at all. When you want to send an associate array simply send it as two separate arrays - one of keys and one of values. Here's the PHP code to do that:

    $arWrapper = array();
    $arWrapper['k'] = array_keys($arChoices);
    $arWrapper['v'] = array_values($arChoices);
    $json = json_encode($arWrapper);

and the simple JavaScript code to do whatever you'd like with it

            for (i=0; i < data['k'].length; i++) {
                console.log('key:' + data['k'][i] + ' val:' + data['v'][i]);
            }

I had a similar issue and posted on jQuery: $.getJSON sorting the data on Chrome / IE?


There are some cases where you will need to use the record id to group things in a post process loop. Putting quotes around the key value will work. Or you can use array_merge on the final array which resets the keys.

$processed_array = array(
  235=>array("id"=>235,"name"=>"Something"),
  27=>array("id"=>27,"name"=>"Something")
);

array_merge($processed_array);

A print_r($processed_array); now returns the following:

$processed_array = array(
  0=>array("id"=>235,"name"=>"Something"),
  1=>array("id"=>27,"name"=>"Something")
);

Unless that JSON is an array, rather than an object, there is no standard that says it has to be in a certain order. However, this shouldn't be a problem since you don't need to iterate through the object to get the data, you can simply refer to the property.


You need to trick Google Chrome (and others) into thinking you have a string and not a number. Changing the JSON to {"2423":'abc', "2555":'xyz'} will not work.

I had to use "_2423" and "_2555" as indexes in my object to get it to work.

Further, debugging the output to console.log or using for x in y gave different results as to _.each method (see the underscore framework).

You can see my test/proof in JSFiddle with "_" vs no prefix and the for x in y loop: http://jsfiddle.net/3f9jugtg/1/







opera