Trier le tableau d'objets dans un ordre spécifique

J'ai un ensemble d'objets renvoyant d'un appel API dont j'ai besoin pour trier dans un format spécifique.

J'essaie d'organiser le destination_country_id par ordre alphabétique sauf pour les trois premiers et derniers éléments. Par exemple, comme ceci:

  1. "Irlande"
  2. "Royaume-Uni"
  3. "États Unis"
  4. … d'autres pays, par ordre alphabétique …
  5. "Partout ailleurs"

J'ai envisagé d'utiliser array.sort() , ce qui, je comprends, je peux facilement utiliser pour les trier par ordre alphabétique, mais j'ai jusqu'à présent échoué à comprendre comment je peux atteindre la sortie souhaitée.

Réponse de l'API

 [ { "destination_country_id":null, "primary_cost":"9.50", "region_id":null, "destination_country_name":"Everywhere Else", }, { "destination_country_id":105, "primary_cost":"8.00", "region_id":null, "destination_country_name":"United Kingdom", }, { "destination_country_id":209, "primary_cost":"9.50", "region_id":null, "destination_country_name":"United States", }, { "destination_country_id":123, "primary_cost":"5.00", "region_id":null, "destination_country_name":"Ireland", }, { "destination_country_id":185, "primary_cost":"5.00", "region_id":null, "destination_country_name":"France", }, { "destination_country_id":145, "primary_cost":"5.00", "region_id":null, "destination_country_name":"Spain", } ] 

Peut-être n'est-ce pas la méthode la plus efficace, mais c'est ES3, ne nécessite aucune bibliothèque et est assez facile à comprendre. En supposant également que vous souhaitez trier par ordre alphabétique sur destination_country_name

Javascript

 // where x is your array of objects x.sort(function (a, b) { // sorts everything alphabetically return a.destination_country_name.localeCompare(b.destination_country_name); }).sort(function (a, b) { // moves only this to country to top return +(!b.destination_country_name.localeCompare('United States')); }).sort(function (a, b) { // moves only this to country to top return +(!b.destination_country_name.localeCompare('United Kingdom')); }).sort(function (a, b) { // moves only this to country to top return +(!b.destination_country_name.localeCompare('Ireland')); }).sort(function (a, b) { // moves only this to country to bottom return +(!a.destination_country_name.localeCompare('Everywhere Else')); }); console.log(JSON.stringify(x, ['destination_country_name'])); 

Sortie

 [{"Destination_country_name": "Irlande"},
  {"Destination_country_name": "Royaume-Uni"},
  {"Destination_country_name": "United States"},
  {"Destination_country_name": "France"},
  {"Destination_country_name": "Espagne"},
  {"Destination_country_name": "Partout ailleurs"}]

Sur jsFiddle

Nous pourrions même aller plus loin et utiliser l'exemple ci-dessus pour créer une fonction réutilisable, comme.

Javascript

 function sorter(array, funcs, orders) { funcs = funcs || {}; orders = orders || {}; array.sort(funcs.general); if (Array.isArray(orders.top)) { orders.top.slice().reverse().forEach(function(value) { array.sort(funcs.top.bind(value)); }); } if (Array.isArray(orders.bottom)) { orders.bottom.forEach(function(value) { array.sort(funcs.bottom.bind(value)); }); } return array; } sorter(x, { general: function (a, b) { return a.destination_country_name.localeCompare(b.destination_country_name); }, top: function (a, b) { return +(!b.destination_country_name.localeCompare(this)); }, bottom: function (a, b) { return +(!a.destination_country_name.localeCompare(this)); } }, { top: ['Ireland', 'United Kingdom', 'United States'], bottom: ['Everywhere Else'] }); 

Sur jsFiddle

Et maintenant, vous pouvez trier facilement différents attributs en analysant dans différentes fonctions de comparaison, et définir des valeurs qui devraient être en haut ou en bas.

J'ai utilisé les méthodes ECMA5, mais vous pourriez aussi facilement le faire avec ECMA3.

Je pense que le moyen le plus efficace de trier votre gamme est de trouver d'abord où "Everywhere Else" , "UK" , "Ireland" et "US" sont dans votre tableau, les supprimer, puis trier le reste du tableau . C'est plus simple que cela semble

violon

 var data = [ {"destination_country_name": "Everywhere Else"}, {"destination_country_name": "United Kingdom"}, {"destination_country_name": "United States"}, {"destination_country_name": "Ireland"}, {"destination_country_name": "France"}, {"destination_country_name": "Spain"} ]; //removed the other elements just to make the example cleaner var keep = ["Everywhere Else", "Ireland", "United Kingdom", "United States"]; //keep is the elements you want in the front; order them exactly at you want them ordered var top = []; //this is our holder array to hold the objects for the strings in keep for (var i = 0; i < keep.length; i++) { var index = function () { for (var j = 0; j < data.length; j++){ //loop through data if (data[j].destination_country_name == keep[i]) return data[j]; //return the object if it's name matches the one in keep } } if (index > -1){ //if the object is in the array (index != -1) top.push(data[index]); //push the object to our holder array data.splice(index, 1); //splice the object out of the original array } } //after this loop, those other objects will have been removed //sort the rest of that array of objects data.sort(function (a, b) { //use a callback function to specify which parts of //the object need to be sorted //basic sorting/compare algorithm (-1, 0, or 1) if (a.destination_country_name > b.destination_country_name) return 1; //if greater if (a.destination_country_name < b.destination_country_name) return -1; //if lesser return 0; //otherwise }) var sorted = top.concat(data), //combine data to the holder array and assign to sorted extra = sorted.shift(); //grab the first element ("Everywhere Else") and remove it sorted.push(extra); //add that element to the end of the array console.log(sorted); 

Sinon, si vous connaissez ces quatre endroits (EE, Royaume-Uni, États-Unis et Irlande) seront toujours les 4 premiers éléments de votre tableau, vous pouvez faire ce qui suit:

 var data = [ {"destination_country_name": "Everywhere Else"}, {"destination_country_name": "United Kingdom"}, {"destination_country_name": "United States"}, {"destination_country_name": "Ireland"}, {"destination_country_name": "France"}, {"destination_country_name": "Spain"} ]; var top = data.slice(0,4); data.sort(function (a, b) { if (a.destination_country_name > b.destination_country_name) return 1; if (a.destination_country_name < b.destination_country_name) return -1; return 0; }) var sorted = top.concat(data), extra = sorted.shift(); sorted = sorted.push(extra); //put "Everywhere Else" at the end of the array 

Notez comment cela est beaucoup plus efficace (et beaucoup plus simple!) Car il n'est pas nécessaire de localiser ces quatre éléments.

Vous pouvez donner à chaque objet une propriété "tri". Spécifiez les 3 premiers connus et le dernier, et donnez à tous les autres la même valeur, plus grand que les trois premiers et moins que le dernier. Ensuite, trier le tableau – d'abord par ordre de tri, puis par ordre alphabétique;

Var arr = [{"destination_country_id": null, "primary_cost": "9.50", "region_id": null, "destination_country_name": "Everywhere Else",}, {"destination_country_id": 105, "primary_cost": "8.00" , "Region_id": null, "destination_country_name": "United Kingdom",}, {"destination_country_id": 209, "primary_cost": "9.50", "region_id": null, "destination_country_name": "United States",} {"Destination_country_id": 123, "primary_cost": "5.00", "region_id": null, "destination_country_name": "Ireland",}, {"destination_country_id": 185, "primary_cost": "5.00", "region_id": Null, "destination_country_name": "France",}, {"destination_country_id": 145, "primary_cost": "5.00", "region_id": nul, "destination_country_name": "Espagne",}]

 var s= "destination_country_name", order= ["Ireland", "United Kingdom", "United States", "Everywhere Else"]; arr.forEach(function(itm){ var i= order.indexOf(itm[s]); if(i!= -1) itm.sort_order= i== 3? 1e50: i; else itm.sort_order= 10; }); arr.sort(function(a, b){ var d= a.sort_order- b.sort_order; if(d===0){ if(a[s]=== b[s]) return 0; return a[s]>b[s]? 1: -1; } return d; }); JSON.stringify(arr) /* returned value: (String)[{ "destination_country_id": 123, "primary_cost": "5.00", "region_id": null, "destination_country_name": "Ireland", "sort_order": 0 },{ "destination_country_id": 105, "primary_cost": "8.00", "region_id": null, "destination_country_name": "United Kingdom", "sort_order": 1 },{ "destination_country_id": 209, "primary_cost": "9.50", "region_id": null, "destination_country_name": "United States", "sort_order": 2 },{ "destination_country_id": 185, "primary_cost": "5.00", "region_id": null, "destination_country_name": "France", "sort_order": 10 },{ "destination_country_id": 145, "primary_cost": "5.00", "region_id": null, "destination_country_name": "Spain", "sort_order": 10 },{ "destination_country_id": null, "primary_cost": "9.50", "region_id": null, "destination_country_name": "Everywhere Else", "sort_order": 1e+50 } ] */ 

Si votre tableau fourni est appelé list , vous pouvez le trier comme vous le souhaitez en utilisant l'appel suivant:

 list.sort(function (item1, item2) { if (item1.destination_country_name < item2.destination_country_name) { return -1; } return 1; }); 

Vous pouvez utiliser la méthode de classement de soulignement:

 a=[{obj:'first3'},{obj:'first2'},{obj:'first1'},{obj:'z'},{obj:'m'},{obj:'c'},{obj:'end3'},{obj:'end2'},{obj:'end1'}] a=_.sortBy(a,function (t,i){if (i<=2) return String.fromCharCode(0);if(i>=a.length-3) return String.fromCharCode(255);return t.obj }) console.log(JSON.stringify(a)) [{"obj":"first3"},{"obj":"first2"},{"obj":"first1"},{"obj":"c"},{"obj":"m"},{"obj":"z"},{"obj":"end3"},{"obj":"end2"},{"obj":"end1"}] 

http://jsfiddle.net/43Q8h/