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

泪湿孤枕 提交于 2019-11-26 20:13:13

Had same problem, followed dmc's solution but just added a space in front of the int value to make it a string.

The advantage of using a space rather than another non numeric character is that the subsequently POSTed value can be used directly in a mySQL search clause without having to remove it again.

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.

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"}};

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.

Some browsers will sort keys which are int, on the other hand it's very easy to change that to string and later revert, mine solution was to add "i" to key, that made a trick. Works perfectly for each browsers :) Hope that helps :)

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?

None of the solutions worked for me (Aug 2017). Even if I used a string Chrome and Safari (didnt test other browsers) were still sorting based on the string. What I did instead was concatenate my integer key with value string. e.g

result[string_value + str(integer_key)] = string_value

This way the string is first and the browser is free to sort. Then I used some simple logic to separate the key from the value.

Hope this helps.

Collector

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?

user1039177

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;

...

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/

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

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")
);

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 had the same issue with chrome, so frustrating. I send it a certain way, why can't chrome just take my word for it? I get that there's no "standard" way, but if that's the case, why impose your own order??

Anyway, I handled it by turning my objects into arrays, so that

{ 0: "", 2: "Frame", 1: "Masonry" }

became

[[ 0, "" ], [ 2, "Frame" ], [ 1, "Masonry" ]]

Had to change some javascript, but it ended up working perfectly.

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 :)

When you pass the data object to console.log, JavaScript will end up calling the toString() method for the data object. Since you don't like the default format of data's toString() method, you'll have to do the work yourself.

You can dump the object's fields yourself if you want that type of control - you'd have to get the keys/fields and sort them and then build the string version yourself.

something like:

for (field in obj)
    add field to array

sort array into whatever order you want

for (field in array)
    get value of field from obj
    create string of field : value, append to main string

console.log(main string)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!