Как остановить сортировку объектов JSON в Chrome и Opera по индексу ASC? - PullRequest
60 голосов
/ 16 февраля 2011

У меня проблема.

Используя ajax, я отправил правильно сформированный объект JSON, используя:

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

Однако Opera и Chrome, хотя и получают один и тот же объект, распечатывают объект в неправильном порядке, похоже, что они оба выполняют сортировку по номеру ID, а не просто оставляют его в покое!

Есть ли способ остановить эту автосортировку?

Редактировать, узнав, что это сортировка по номеру индекса, я думаю, что лучшим способом может быть не использовать индекс для хранения object_id, а вместо этого сохранить номер идентификатора, по которому я хочу упорядочить объект.

Однако я все же хотел бы знать, есть ли способ остановить сортировку.

Спасибо

Edit2, я просто хотел бы отметить, что я собираюсь работать над другим способом сделать это, так как я чувствую, что я злоупотребляю объектами с помощью этого метода. Однако я все еще хотел бы понять, почему Opera и Chrome считают, что они имеют право изменять порядок идентификаторов моих объектов:

Проблема заключается в том, что я пытаюсь сэкономить вычислительную мощность, скажем, у нас есть люди с ID,

1.Джон, 2.Франк и 3.Салли. Однако у каждого из этих людей есть набор свойств высоты (и другие вещи). 1.Дж.180, 2.Франк.220, 3.Салли.150. Чтобы сэкономить на обработке, я запрашиваю, чтобы результаты людей сортировались по их росту, поэтому я получаю массив 2, 1, 3 с другими их свойствами. Я JSON этот массив и отправить его в браузер.

Теперь FF сохранит новый порядок Люди [1] все равно были бы Джоном, но в цикле For n как человек они будут не в порядке.

Если я не смогу обойти это, мне просто не нужно будет заниматься сортировкой на этапе SQL и добавить дополнительные циклы и сортировку в массив на этапе JS, хотя я хотел избежать большей нагрузки на браузер, так как это уже тяжелая страница Js.

Большое спасибо

Ответы [ 16 ]

23 голосов
/ 07 сентября 2012

Имела ту же проблему, следуя решению dmc, но добавила пробел перед значением int, чтобы сделать его строкой.

Преимущество использования пробела, а не другого нечислового символа, заключается в том, что впоследствии POSTзначение может быть использовано непосредственно в предложении поиска MySQL без необходимости его повторного удаления.

19 голосов
/ 23 февраля 2011

Различные браузеры обрабатывают объекты по-разному, моя вина была в том, чтобы попытаться использовать порядок, в котором я построил объект, в качестве ссылки, где я не должен.

18 голосов
/ 21 сентября 2012

Изменение целого числа на строку у меня не сработало (Chrome, jQuery 1.7.1).Таким образом, чтобы сохранить порядок (да, это злоупотребление объектом), я изменил это:

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

на это

optionValues0 = {"1": {id: "4321", value: "option 1"}, "2": {id: "1234", value: "option 2"}};
14 голосов
/ 16 февраля 2011

Если JSON не является массивом, а не объектом, не существует стандарта, который говорит, что он должен быть в определенном порядке. Однако это не должно быть проблемой, так как вам не нужно перебирать объект для получения данных, вы можете просто обратиться к свойству.

6 голосов
/ 21 июня 2012

Некоторые браузеры сортируют ключи, которые являются int, с другой стороны, очень легко изменить их на string и позже вернуть, мое решение состояло в том, чтобы добавить «i» к ключу, что сделало трюк. Отлично работает для каждого браузера :) Надеюсь, это поможет :)

5 голосов
/ 23 февраля 2011

У меня была та же «проблема», и я не хотел возвращаться и слишком сильно менять код.Выяснил, что по крайней мере Google Chrome только пересортирует числовые индексы.Пока индекс считается строкой, он будет отображаться в «заданном» порядке.Может кто-нибудь проверить это в Opera?

2 голосов
/ 01 августа 2017

Ни одно из решений не сработало для меня (август 2017 г.).Даже если бы я использовал строку, Chrome и Safari (не тестировал другие браузеры) все равно сортировали по строке.Вместо этого я соединил свой целочисленный ключ со строкой значения.например,

result[string_value + str(integer_key)] = string_value

Таким образом, строка является первой, и браузер может свободно сортировать.Затем я использовал простую логику, чтобы отделить ключ от значения.

Надеюсь, это поможет.

1 голос
/ 19 августа 2013

Я решил эту проблему, используя этот код:

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

и в 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;

...
1 голос
/ 26 ноября 2012

Вам нужно обмануть Google Chrome (и других), чтобы он думал, что у вас есть строка, а не число. Изменение JSON на {"2423":'abc', "2555":'xyz'} не будет работать.

Мне пришлось использовать "_2423" и "_2555" в качестве индексов в моем объекте, чтобы заставить его работать.

Кроме того, отладка вывода в console.log или использование for x in y дали другие результаты в отношении метода _.each (см. Структуру подчеркивания).

Вы можете увидеть мой тест / доказательство в JSFiddle с "_" против префикса и циклом for x in y: http://jsfiddle.net/3f9jugtg/1/

1 голос
/ 29 февраля 2012

Кажется, лучший способ - вообще избегать ассоциативных массивов. Если вы хотите отправить ассоциированный массив, просто отправьте его как два отдельных массива - один из ключей и один из значений. Вот код PHP для этого:

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

и простой код JavaScript, чтобы делать с ним что угодно

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

У меня была похожая проблема, и я разместил на jQuery: $ .getJSON сортировку данных в Chrome / IE?

...