61 votes

Tri de JSON par valeurs

J'ai un objet JSON très simple comme le suivant :

{
   "people":[
      {
         "f_name":"john",
         "l_name":"doe",
         "sequence":"0",
         "title":"president",
         "url":"google.com",
         "color":"333333"
      },
      {
         "f_name":"michael",
         "l_name":"goodyear",
         "sequence":"0",
         "title":"general manager",
         "url":"google.com",
         "color":"333333"
      }
   ]
}

Maintenant qu'il est renvoyé par mon code côté serveur, j'exécute jQuery.each pour former le html nécessaire et sortir le résultat.

Actuellement, ce que je fais est d'envoyer un appel AJAX au serveur contenant mes informations de tri... par exemple "Title DESC" et de réexécuter une requête SQL pour renvoyer le nouvel ensemble de résultats. Mais je veux éviter cela et utiliser jQuery pour trier le JSON résultant afin d'éviter les allers-retours vers le serveur et les accès multiples aux bases de données.

Comment puis-je réaliser cela en utilisant jQuery ?

0 votes

Vous pourriez essayer une variation de ceci : wrichards.com/blog/2009/02/jquery-sorting-elements

1 votes

Juste pour info... vous pouvez utiliser n'importe quel tutoriel sur internet sur le tri des tableaux en javascript et il s'appliquera directement à votre scénario puisque JSON est simplement un objet/réseau en javascript. JS ne fait pas de différence entre les objets et les tableaux puisque tout est fondamentalement un objet en JS de toute façon :-)

0 votes

@Emin, veuillez envisager de modifier la réponse acceptée, puisque la réponse que j'ai fournie a maintenant reçu presque deux fois plus de votes positifs que la réponse précédemment acceptée.

124voto

Sean the Bean Points 819

JQuery n'est pas particulièrement utile pour le tri, mais voici une solution élégante et efficace. Il suffit d'écrire une simple fonction JS qui prend le nom de la propriété et l'ordre (croissant ou décroissant) et appelle la méthode native sort() avec une simple fonction de comparaison :

var people = [
    {
        "f_name": "john",
        "l_name": "doe",
        "sequence": "0",
        "title" : "president",
        "url" : "google.com",
        "color" : "333333",
    }
    // etc
];

function sortResults(prop, asc) {
    people.sort(function(a, b) {
        if (asc) {
            return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);
        } else {
            return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);
        }
    });
    renderResults();
}

Ensuite :

sortResults('l_name', true);

Jouez avec un exemple fonctionnel aquí .

2 votes

Cela ne semble pas fonctionner pour moi lorsque je mets quelques lignes de données supplémentaires. Il semble que le tri soit différent à chaque fois que j'essaie. Voici le test : jsfiddle.net/Jsar8 Toute aide est appréciée.

1 votes

Étonnamment, Chrome (ainsi que d'autres navigateurs importants) n'utilise pas d'algorithme de tri "stable" (c'est-à-dire cohérent ?). Les questions suivantes proposent une bonne discussion sur les méthodes de tri des navigateurs : stackoverflow.com/questions/1427608/ stackoverflow.com/questions/234683/ stackoverflow.com/questions/3026281/

0 votes

Limite importante : La fonction de tri de base fonctionnait sur FF, elle échoue sur Chrome 24, elle échoue sur le navigateur par défaut d'Android. jsfiddle.net/VAKrE/377 La fonction était par ailleurs élégante !

25voto

Hugolpz Points 2062

Démonstration : https://jsfiddle.net/kvxazhso/

Réussir à passer des valeurs égales (garder le même ordre). Flexible : gère l'ascendant (123) ou le descendant (321), fonctionne pour les chiffres, les lettres et les unicodes. Fonctionne sur tous les appareils testés (Chrome, navigateur par défaut d'Android, FF).

Compte tenu de données telles que :

var people = [ 
{ 'myKey': 'A', 'status': 0 },
{ 'myKey': 'B', 'status': 3 },
{ 'myKey': 'C', 'status': 3 },
{ 'myKey': 'D', 'status': 2 },
{ 'myKey': 'E', 'status': 7 },
...
];

Triage par ordre croissant ou inverse :

function sortJSON(arr, key, way) {
    return arr.sort(function(a, b) {
        var x = a[key]; var y = b[key];
        if (way === '123') { return ((x < y) ? -1 : ((x > y) ? 1 : 0)); }
        if (way === '321') { return ((x > y) ? -1 : ((x < y) ? 1 : 0)); }
    });
}

people2 = sortJSON(people,'status', '321'); // 123 or 321
alert("2. After processing (0 to x if 123; x to 0 if 321): "+JSON.stringify(people2));

12voto

Tahir Akhtar Points 5843
jQuery.fn.sort = function() {  
    return this.pushStack( [].sort.apply( this, arguments ), []);  
};  

 function sortLastName(a,b){  
     if (a.l_name == b.l_name){
       return 0;
     }
     return a.l_name> b.l_name ? 1 : -1;  
 };  
  function sortLastNameDesc(a,b){  
     return sortLastName(a,b) * -1;  
 };
var people= [
{
"f_name": "john",
"l_name": "doe",
"sequence": "0",
"title" : "president",
"url" : "google.com",
"color" : "333333",
},
{
"f_name": "michael",
"l_name": "goodyear",
"sequence": "0",
"title" : "general manager",
"url" : "google.com",
"color" : "333333",
}]

sorted=$(people).sort(sortLastNameDesc);

0 votes

Voir mon adaptation du code de Bill Richards. Il s'agit de trier un tableau json basé sur le nom de famille en ordre décroissant. Le callback de tri peut être généralisé en passant le nom du champ dans le constructeur de la fonction.

1 votes

Vous devez remplacer innerHTML avec l_name dans sortLastName

0 votes

Pour clarifier mon premier commentaire, ce que je veux dire, c'est que ce code peut être encore modifié pour prendre en charge le tri générique.

7voto

tcql Points 86

Si cela ne vous dérange pas d'utiliser une bibliothèque externe, Lodash possède de nombreux utilitaires merveilleux

var people = [
  {
     "f_name":"john",
     "l_name":"doe",
     "sequence":"0",
     "title":"president",
     "url":"google.com",
     "color":"333333"
  },
  {
     "f_name":"michael",
     "l_name":"goodyear",
     "sequence":"0",
     "title":"general manager",
     "url":"google.com",
     "color":"333333"
  }
];

var sorted = _.sortBy(people, "l_name")

Vous pouvez également trier par plusieurs propriétés. Voici un plunk le montrant en action

1voto

krlzlx Points 6

Solution travaillant avec différents types et avec des majuscules et des minuscules.
Par exemple, sans le toLowerCase "Goodyear" viendra avant "doe" avec un tri ascendant. Exécutez l'extrait de code au bas de ma réponse pour voir les différents comportements.

DONNÉES JSON :

var people = [
{
    "f_name" : "john",
    "l_name" : "doe", // lower case
    "sequence": 0 // int
},
{
    "f_name" : "michael",
    "l_name" : "Goodyear", // upper case
    "sequence" : 1 // int
}];

Fonction de tri JSON :

function sortJson(element, prop, propType, asc) {
  switch (propType) {
    case "int":
      element = element.sort(function (a, b) {
        if (asc) {
          return (parseInt(a[prop]) > parseInt(b[prop])) ? 1 : ((parseInt(a[prop]) < parseInt(b[prop])) ? -1 : 0);
        } else {
          return (parseInt(b[prop]) > parseInt(a[prop])) ? 1 : ((parseInt(b[prop]) < parseInt(a[prop])) ? -1 : 0);
        }
      });
      break;
    default:
      element = element.sort(function (a, b) {
        if (asc) {
          return (a[prop].toLowerCase() > b[prop].toLowerCase()) ? 1 : ((a[prop].toLowerCase() < b[prop].toLowerCase()) ? -1 : 0);
        } else {
          return (b[prop].toLowerCase() > a[prop].toLowerCase()) ? 1 : ((b[prop].toLowerCase() < a[prop].toLowerCase()) ? -1 : 0);
        }
      });
  }
}

Utilisation :

sortJson(people , "l_name", "string", true);
sortJson(people , "sequence", "int", true);

var people = [{
  "f_name": "john",
  "l_name": "doe",
  "sequence": 0
}, {
  "f_name": "michael",
  "l_name": "Goodyear",
  "sequence": 1
}, {
  "f_name": "bill",
  "l_name": "Johnson",
  "sequence": 4
}, {
  "f_name": "will",
  "l_name": "malone",
  "sequence": 2
}, {
  "f_name": "tim",
  "l_name": "Allen",
  "sequence": 3
}];

function sortJsonLcase(element, prop, asc) {
  element = element.sort(function(a, b) {
    if (asc) {
      return (a[prop] > b[prop]) ? 1 : ((a[prop] < b[prop]) ? -1 : 0);
    } else {
      return (b[prop] > a[prop]) ? 1 : ((b[prop] < a[prop]) ? -1 : 0);
    }
  });
}

function sortJson(element, prop, propType, asc) {
  switch (propType) {
    case "int":
      element = element.sort(function(a, b) {
        if (asc) {
          return (parseInt(a[prop]) > parseInt(b[prop])) ? 1 : ((parseInt(a[prop]) < parseInt(b[prop])) ? -1 : 0);
        } else {
          return (parseInt(b[prop]) > parseInt(a[prop])) ? 1 : ((parseInt(b[prop]) < parseInt(a[prop])) ? -1 : 0);
        }
      });
      break;
    default:
      element = element.sort(function(a, b) {
        if (asc) {
          return (a[prop].toLowerCase() > b[prop].toLowerCase()) ? 1 : ((a[prop].toLowerCase() < b[prop].toLowerCase()) ? -1 : 0);
        } else {
          return (b[prop].toLowerCase() > a[prop].toLowerCase()) ? 1 : ((b[prop].toLowerCase() < a[prop].toLowerCase()) ? -1 : 0);
        }
      });
  }
}

function sortJsonString() {
  sortJson(people, 'l_name', 'string', $("#chkAscString").prop("checked"));
  display();
}

function sortJsonInt() {
  sortJson(people, 'sequence', 'int', $("#chkAscInt").prop("checked"));
  display();
}

function sortJsonUL() {
  sortJsonLcase(people, 'l_name', $('#chkAsc').prop('checked'));
  display();
}

function display() {
  $("#data").empty();
  $(people).each(function() {
    $("#data").append("<div class='people'>" + this.l_name + "</div><div class='people'>" + this.f_name + "</div><div class='people'>" + this.sequence + "</div><br />");
  });
}

body {
  font-family: Arial;
}
.people {
  display: inline-block;
  width: 100px;
  border: 1px dotted black;
  padding: 5px;
  margin: 5px;
}
.buttons {
  border: 1px solid black;
  padding: 5px;
  margin: 5px;
  float: left;
  width: 20%;
}
ul {
  margin: 5px 0px;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons" style="background-color: rgba(240, 255, 189, 1);">
  Sort the JSON array <strong style="color: red;">with</strong> toLowerCase:
  <ul>
    <li>Type: string</li>
    <li>Property: lastname</li>
  </ul>
  <button onclick="sortJsonString(); return false;">Sort JSON</button>
  Asc Sort
  <input id="chkAscString" type="checkbox" checked="checked" />
</div>
<div class="buttons" style="background-color: rgba(255, 214, 215, 1);">
  Sort the JSON array <strong style="color: red;">without</strong> toLowerCase:
  <ul>
    <li>Type: string</li>
    <li>Property: lastname</li>
  </ul>
  <button onclick="sortJsonUL(); return false;">Sort JSON</button>
  Asc Sort
  <input id="chkAsc" type="checkbox" checked="checked" />
</div>
<div class="buttons" style="background-color: rgba(240, 255, 189, 1);">
  Sort the JSON array:
  <ul>
    <li>Type: int</li>
    <li>Property: sequence</li>
  </ul>
  <button onclick="sortJsonInt(); return false;">Sort JSON</button>
  Asc Sort
  <input id="chkAscInt" type="checkbox" checked="checked" />
</div>
<br />
<br />
<div id="data" style="float: left; border: 1px solid black; width: 60%; margin: 5px;">Data</div>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X