web-dev-qa-db-fra.com

Comment arrêter le tri des objets JSON par Chrome et Opera par Index ASC?

J'ai un problème.

En utilisant ajax, j'ai envoyé un objet JSON correctement formé en utilisant:

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

Cependant, Opera et Chrome, bien que recevant le même objet, impriment l'objet dans un ordre incorrect. Il semble qu'ils effectuent tous les deux un tri par numéro d'identification au lieu de le laisser seul!

Y a-t-il un moyen d'arrêter ce tri automatique?

Modifier, après avoir découvert qu’il s’agissait d’un tri par numéro d’index, je pense que la meilleure méthode pourrait être de ne pas utiliser l’index pour stocker le object_id, mais plutôt le numéro d’identification par lequel je souhaite classer l’objet.

Cependant, j'aimerais quand même savoir s'il existe un moyen d'arrêter le tri.

Je vous remercie

Edit2, je voudrais juste noter que je vais travailler sur une manière différente de procéder, car je sens que j'abuse des objets avec cette méthode. Cependant, j'aimerais toujours comprendre pourquoi Opera et Chrome estiment que c'est leur droit de changer l'ordre des ID de mes objets:

Le problème serait que je cherche à économiser de la puissance de traitement, disons que nous avons des personnes avec un ID,

1.John, 2.Frank et 3.Sally. Cependant, chacune de ces personnes possède un ensemble de propriétés élevé (et d'autres éléments). 1.John.180, 2.Frank.220, 3.Sally.150. Pour économiser sur le traitement, je demande que le résultat des personnes soit trié par leur hauteur afin que je reçoive un tableau de 2, 1, 3 avec leurs autres propriétés. Je JSON ce tableau et l'envoyer au navigateur.

Maintenant, FF conservera le nouvel ordre Les personnes [1] seraient toujours John, mais dans une boucle For n as person, elles seraient en panne.

Si je ne parviens pas à résoudre ce problème, je n'aurai plus besoin de trier au stade SQL et d'ajouter des boucles et du tri supplémentaires dans un tableau au stade JS, même si je voulais éviter davantage de stress sur le navigateur, car il est déjà lourd. page.

Merci beaucoup

59
Dorjan

Différents navigateurs traitent les objets de différentes manières, ma faute étant d'essayer d'utiliser l'ordre dans lequel j'ai construit un objet comme référence là où je ne devrais pas.

19
Dorjan

Même problème, suivi de la solution de dmc, mais ajout d’un espace devant la valeur int pour en faire une chaîne.

L'avantage d'utiliser un espace plutôt qu'un autre caractère non numérique est que la valeur POSTed ultérieure peut être utilisée directement dans une clause de recherche mySQL sans qu'il soit nécessaire de la supprimer à nouveau.

23
FarnhamBee

Changer le nombre entier en chaîne ne fonctionnait pas pour moi (Chrome, jQuery 1.7.1) . Donc, pour conserver l'ordre (oui, c'est un abus de l'objet), j'ai changé ceci:

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

pour ça

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

À moins que JSON soit un tableau plutôt qu'un objet, il n'existe aucune norme indiquant qu'il doit figurer dans un certain ordre. Toutefois, cela ne devrait pas poser de problème, car vous n'avez pas besoin de parcourir l'objet pour obtenir les données, vous pouvez simplement faire référence à la propriété.

14
James Long

Certains navigateurs vont trier les clés qui sont entières, d’autre part, il est très facile de changer cela en chaîne et de revenir plus tard, ma solution consistait à ajouter "i" à la clé, ce qui était une astuce. Fonctionne parfaitement pour chaque navigateur :) Espérons que cela aide :) 

6
dmc

J'ai eu le même "problème" et je ne voulais pas revenir en arrière et changer trop dans le code. Compris qu'au moins Google Chrome ne trie à nouveau que les index numériques. Tant que l'index est considéré comme une chaîne, il apparaîtra dans l'ordre "prévu". Quelqu'un pourrait-il s'il vous plaît vérifier cela sur Opera?

5
Alasjo

Aucune des solutions n'a fonctionné pour moi (août 2017). Même si j'utilisais une chaîne, Chrome et Safari (je n'ai pas testé d'autres navigateurs) continuaient à trier en fonction de la chaîne. Ce que j'ai fait à la place a été de concaténer ma clé entière avec une chaîne de valeur. par exemple

result[string_value + str(integer_key)] = string_value

De cette façon, la chaîne est la première et le navigateur est libre de trier. Ensuite, j'ai utilisé une logique simple pour séparer la clé de la valeur.

J'espère que cela t'aides.

2
user3167654

Le meilleur moyen semble être d'éviter les tableaux associatifs. Lorsque vous souhaitez envoyer un tableau associé, il vous suffit de l’envoyer sous forme de deux tableaux distincts: l’une des clés et l’autre des valeurs. Voici le code PHP pour le faire:

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

et le code JavaScript simple pour faire ce que vous voulez avec

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

J'ai eu un problème similaire et posté sur jQuery: $ .getJSON triant les données sur Chrome/IE?

1
Collector

Vous devez tromper Google Chrome (et d'autres) en leur faisant croire que vous avez une chaîne et non un nombre . Changer le JSON en {"2423":'abc', "2555":'xyz'} ne fonctionnera pas.

Je devais utiliser "_2423" et "_2555" comme index dans mon objet pour que cela fonctionne. 

En outre, le débogage de la sortie vers console.log ou l’utilisation de for x in y donnait des résultats différents de ceux de la méthode _.each (voir la structure de soulignement).

Vous pouvez voir mon test/preuve dans JSFiddle avec "_" sans préfixe et avec la boucle for x in y: http://jsfiddle.net/3f9jugtg/1/

1
DynamicDan

J'ai résolu ce problème en utilisant ce code:

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

et dans 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
user1039177

Faites votre identifiant d'objet dans le paramètre de chaîne JSON, cela fonctionne sans tri automatique.

0
Alexej Nagel

J'ai eu le même problème et il m'a fallu un certain temps pour déterminer ce qui le causait, quelle douleur. J'ai fini par supprimer l'ID de l'index et ai utilisé array_Push, au lieu d'être:

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

etc. je l'ai changé pour

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

Ce qui m'a permis de garder l'ordre de PHP puisque les nouveaux index étaient déjà en ordre (0,1,2,3 etc. par opposition à 112, 56, 411, etc.)

0
AersolKing

Dans certains cas, vous devrez utiliser l'ID d'enregistrement pour regrouper des éléments dans une boucle de post-traitement. Mettre des guillemets autour de la valeur clé fonctionnera. Ou vous pouvez utiliser array_merge sur le tableau final qui réinitialise les clés.

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

array_merge($processed_array);

Un print_r ($ processing_array); renvoie maintenant ce qui suit:

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

J'ai eu le même problème avec le chrome, tellement frustrant. Je l'envoie d'une certaine manière, pourquoi chrome ne peut-il pas prendre ma parole pour cela? Je comprends qu'il n'y a pas de méthode "standard", mais si c'est le cas, pourquoi imposer votre propre ordre ??

Quoi qu'il en soit, je l'ai manipulé en transformant mes objets en tableaux, de sorte que

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

est devenu

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

J'ai dû changer du javascript, mais cela a fini par fonctionner parfaitement.

0
emery.noel

Une astuce qui peut aider est la suivante: 

Vous devez ajouter "i" à la clé pendant que vous préparez vos données pour la boucle, cela a fait un tour. Fonctionne parfaitement pour chaque navigateur. 

par exemple :

 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

Par conséquent, votre objet sera comme suit:

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

j'espère que cela t'aides :)

0
Maulik