Как остановить сортировку объектов JSON в Chrome и Opera по индексу ASC?
У меня проблема.
С помощью ajax я отправил правильно сформированный объект JSON с помощью:
$.ajax({
type: "POST",
url: SITE_URL+'/data.php',
dataType: "json",
data: { ajax: 1 },
success: function(data) {
console.log(data);
}
});
однако Opera и Chrome, хотя и получают один и тот же объект, распечатывают объект в неправильном порядке, похоже, что они оба выполняют сортировку по идентификационному номеру, а не просто оставляют его в покое!
есть ли способ остановить эту автоматическую сортировку?
Edit, узнав, что это сортировка по номеру индекса, я думаю, что лучшим методом может быть не используйте индекс для хранения object_id и вместо этого сохраните идентификационный номер, по которому я хочу заказать объект.
однако я все равно хотел бы знать, есть ли способ остановить сортировку.
спасибо
Edit2, я просто хотел бы отметить, что я собираюсь работать над другим способом сделать это, так как я чувствую, что злоупотребляю объектами с помощью этого метода. Однако я все равно хотел бы понять, почему Opera и Chrome считают, что они имеют право изменять порядок моих объектов Идентификаторы:
проблема будет заключаться в том, что я пытаюсь сэкономить вычислительную мощность, скажем, у нас есть люди с идентификатором,
1.Джон, 2.Фрэнк и 3.Вылазка. Однако у каждого из этих людей есть набор свойств hight (и другие вещи). 1.Джон.180, 2.Откровенный.220, 3.Вылазка.150. Чтобы сэкономить на обработке, я прошу, чтобы результат людей был отсортирован по их высоте, поэтому я получаю массив 2, 1, 3 с их другими свойствами. Я JSON в массив и отправить его в браузер.
теперь FF будет держать новый порядок Люди [1] все равно были бы Джоном, но в цикле для n как человека они будут не в порядке.
Если я не могу обойти это, мне просто нужно не беспокоиться о сортировке на этапе SQL и добавить дополнительный цикл и сортировку в массив на этапе JS, хотя я хотел избежать большего стресса в браузере, поскольку его уже тяжелая страница Js.
большое спасибо
16 ответов:
была такая же проблема, последовала за решением dmc, но просто добавила пробел перед значением int, чтобы сделать его строкой.
преимущество использования пробела, а не другого нечислового символа заключается в том, что впоследствии опубликованное значение может использоваться непосредственно в предложении поиска mySQL без необходимости его повторного удаления.
разные браузеры обрабатывают объекты по-разному, моя ошибка заключалась в том, чтобы попытаться использовать порядок, в котором я построил объект в качестве ссылки, где я не должен.
изменение целого числа на строку не сработало для меня (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"}};
Если JSON не является массивом, а не объектом, нет стандарта, который говорит, что он должен быть в определенном порядке. Однако это не должно быть проблемой, так как вам не нужно перебирать объект, чтобы получить данные, вы можете просто обратиться к свойству.
некоторые браузеры будут сортировать ключи, которые являются int, с другой стороны, очень легко изменить это на строку, а затем вернуться, мое решение состояло в том, чтобы добавить "i" к ключу, что сделало трюк. Отлично работает для каждого браузера:) надеюсь, что поможет :)
У меня была такая же "проблема" и я не хотел возвращаться и слишком много менять в коде. Выяснил, что по крайней мере Google Chrome только повторно сортирует числовые индексы. Пока индекс считается строкой, он будет отображаться в "предполагаемом" порядке. Может кто-нибудь проверить это на Opera?
ни одно из решений не работало для меня (август 2017). Даже если я использовал строку Chrome и Safari (не тестировал другие браузеры) все еще сортировали на основе строки. Вместо этого я связал свой целочисленный ключ со строкой значения. е.г
result[string_value + str(integer_key)] = string_value
таким образом, строка является первой, и браузер может свободно сортировать. Затем я использовал простую логику, чтобы отделить ключ от значения.
надеюсь, что это помогает.
Кажется, лучший способ-вообще избегать ассоциативных массивов. Если вы хотите отправить ассоциированный массив, просто отправьте его как два отдельных массива - один из ключей и один из значений. Вот 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?
Я решил эту проблему с помощью этого кода:
$('.edit_district').editable("/moderator/sale/edit_sale/", { data : " {'_7':'10 street', '_9':'9 street', '_11':'park'}", type : 'select', submit : 'OK', onblur : 'submit' });
и в сценарий.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; ...
вам нужно обмануть Google Chrome (и другие), думая, что у вас есть строка, а не число. Изменение JSON на
{"2423":'abc', "2555":'xyz'}
не будет работать.мне пришлось использовать" _2423 "и" _2555 " в качестве индексов в моем объекте, чтобы заставить его работать.
далее, отладка вывода на консоль.войти или с помощью
for x in y
дал разные результаты для_.each
метод (см. структуру подчеркивания).вы можете увидеть мой тест / доказательство в JSFiddle с
"_"
против без префикса иfor x in y
цикл:http://jsfiddle.net/3f9jugtg/1/
сделайте свой идентификатор объекта в строковом параметре JSON, он работает без автоматической сортировки.
есть некоторые случаи, когда вам нужно будет использовать идентификатор записи для группировки вещей в цикле post process. Поставив кавычки вокруг значения ключа будет работать. Или вы можете использовать array_merge на конечном массиве, который сбрасывает ключи.
$processed_array = array( 235=>array("id"=>235,"name"=>"Something"), 27=>array("id"=>27,"name"=>"Something") ); array_merge($processed_array);
в print_r($processed_array); теперь возвращает следующее:
$processed_array = array( 0=>array("id"=>235,"name"=>"Something"), 1=>array("id"=>27,"name"=>"Something") );
у меня была та же проблема, и мне потребовалось некоторое время, чтобы понять, что даже вызвало ее, какую боль. Я закончил тем, что удалил ID из индекса и использовал array_push вместо того, чтобы быть:
$section[$s_id]['Type'] = $booktype;
etc. Я изменил его на
array_push($sections, array('ID'=>$s_id, 'CourseID'=>$courseid, 'SectionName'=>$secname, 'Order'=>$order, 'Created'=>$created, 'Description'=>$desc ));
что позволило мне сохранить заказ от PHP, так как новые индексы, где уже в порядке (0,1,2,3 и т. д. В отличие от 112, 56, 411 и т. д.)
у меня была такая же проблема с хромом, очень неприятно. Я отправляю его определенным образом, почему хром не может просто поверить мне на слово? Я понимаю, что нет "стандарта", но если это так, зачем навязывать свой порядок??
в любом случае, я справился с этим, превратив мои объекты в массивы, так что
{ 0: "", 2: "Frame", 1: "Masonry" }
стало
[[ 0, "" ], [ 2, "Frame" ], [ 1, "Masonry" ]]
пришлось изменить некоторые javascript, но он в конечном итоге работает отлично.
один трюк, который может помочь следующим образом:
вы должны добавить "i" к ключу, пока вы готовите свои данные в цикле for, что сделало трюк. Отлично работает для каждого браузера.
например :
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
следовательно, ваш объект будет следующим:
Object {156674: Object, 201705: Object, 329709: Object}
надеюсь, что это помогает :)
при передаче объекта данных в
console.log
, JavaScript в конечном итоге вызоветtoString()
метод для объекта данных. Поскольку вам не нравится формат данных по умолчаниюtoString()
метод, вы должны будете сделать работу самостоятельно.вы можете сбросить поля объекта самостоятельно, если вы хотите, чтобы этот тип управления - вы должны были бы получить ключи/поля и сортировать их, а затем построить версию строки самостоятельно.
что-то типа:
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)