Comment sortinger un tableau sur plusieurs colonnes?

J’ai un tableau multidimensionnel. Le tableau primaire est un tableau de

[publicationID][publication_name][ownderID][owner_name] 

Ce que j’essaie de faire est de sortinger le tableau par owner_name , puis par owner_name . Je sais en JavaScript que vous avez Array.sort() , dans lequel vous pouvez mettre une fonction personnalisée, dans mon cas, j’ai:

 function mysortfunction(a, b) { var x = a[3].toLowerCase(); var y = b[3].toLowerCase(); return ((x  y) ? 1 : 0)); } 

Cela convient parfaitement au sorting sur la colonne, à savoir nom_propriétaire, mais comment le modifier pour sortinger le owner_name , puis le owner_name ?

Si les noms des propriétaires diffèrent, sortingez-les. Sinon, utilisez le nom de publication pour la condition de départage.

 function mysortfunction(a, b) { var o1 = a[3].toLowerCase(); var o2 = b[3].toLowerCase(); var p1 = a[1].toLowerCase(); var p2 = b[1].toLowerCase(); if (o1 < o2) return -1; if (o1 > o2) return 1; if (p1 < p2) return -1; if (p1 > p2) return 1; return 0; } 

Je pense que ce que vous cherchez est thenBy.js: https://github.com/Teun/thenBy.js

Il vous permet d’utiliser le standard Array.sort, mais avec firstBy().thenBy().thenBy() .

Un exemple peut être vu ici .

Nous avons rencontré un besoin de faire des sortingages d’objects et de tableaux mixtes de type SQL par des clés.

La solution de kennebec ci-dessus m’a aidé à y parvenir:

 Array.prototype.keySort = function(keys) { keys = keys || {}; // via // https://stackoverflow.com/questions/5223/length-of-javascript-object-ie-associative-array var obLen = function(obj) { var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) size++; } return size; }; // avoiding using Object.keys because I guess did it have IE8 issues? // else var obIx = function(obj, ix){ return Object.keys(obj)[ix]; } or // whatever var obIx = function(obj, ix) { var size = 0, key; for (key in obj) { if (obj.hasOwnProperty(key)) { if (size == ix) return key; size++; } } return false; }; var keySort = function(a, b, d) { d = d !== null ? d : 1; // a = a.toLowerCase(); // this breaks numbers // b = b.toLowerCase(); if (a == b) return 0; return a > b ? 1 * d : -1 * d; }; var KL = obLen(keys); if (!KL) return this.sort(keySort); for ( var k in keys) { // asc unless desc or skip keys[k] = keys[k] == 'desc' || keys[k] == -1 ? -1 : (keys[k] == 'skip' || keys[k] === 0 ? 0 : 1); } this.sort(function(a, b) { var sorted = 0, ix = 0; while (sorted === 0 && ix < KL) { var k = obIx(keys, ix); if (k) { var dir = keys[k]; sorted = keySort(a[k], b[k], dir); ix++; } } return sorted; }); return this; }; 

exemple d'utilisation:

 var obja = [ {USER:"bob", SCORE:2000, TIME:32, AGE:16, COUNTRY:"US"}, {USER:"jane", SCORE:4000, TIME:35, AGE:16, COUNTRY:"DE"}, {USER:"tim", SCORE:1000, TIME:30, AGE:17, COUNTRY:"UK"}, {USER:"mary", SCORE:1500, TIME:31, AGE:19, COUNTRY:"PL"}, {USER:"joe", SCORE:2500, TIME:33, AGE:18, COUNTRY:"US"}, {USER:"sally", SCORE:2000, TIME:30, AGE:16, COUNTRY:"CA"}, {USER:"yuri", SCORE:3000, TIME:34, AGE:19, COUNTRY:"RU"}, {USER:"anita", SCORE:2500, TIME:32, AGE:17, COUNTRY:"LV"}, {USER:"mark", SCORE:2000, TIME:30, AGE:18, COUNTRY:"DE"}, {USER:"amy", SCORE:1500, TIME:29, AGE:19, COUNTRY:"UK"} ]; var sorto = { SCORE:"desc",TIME:"asc", AGE:"asc" }; obja.keySort(sorto); 

donne les résultats suivants:

  0: { USER: jane; SCORE: 4000; TIME: 35; AGE: 16; COUNTRY: DE; } 1: { USER: yuri; SCORE: 3000; TIME: 34; AGE: 19; COUNTRY: RU; } 2: { USER: anita; SCORE: 2500; TIME: 32; AGE: 17; COUNTRY: LV; } 3: { USER: joe; SCORE: 2500; TIME: 33; AGE: 18; COUNTRY: US; } 4: { USER: sally; SCORE: 2000; TIME: 30; AGE: 16; COUNTRY: CA; } 5: { USER: mark; SCORE: 2000; TIME: 30; AGE: 18; COUNTRY: DE; } 6: { USER: bob; SCORE: 2000; TIME: 32; AGE: 16; COUNTRY: US; } 7: { USER: amy; SCORE: 1500; TIME: 29; AGE: 19; COUNTRY: UK; } 8: { USER: mary; SCORE: 1500; TIME: 31; AGE: 19; COUNTRY: PL; } 9: { USER: tim; SCORE: 1000; TIME: 30; AGE: 17; COUNTRY: UK; } keySort: { } 

(en utilisant une fonction d'impression d' ici )

Voici un exemple de jsbin .

edit: nettoyé et publié en tant que mksort.js sur github .

Ceci est pratique pour les trames alpha de toutes tailles. Transmettez-lui les index que vous souhaitez sortinger, dans l’ordre, en arguments.

 Array.prototype.deepSortAlpha= function(){ var itm, L=arguments.length, order=arguments; var alphaSort= function(a, b){ a= a.toLowerCase(); b= b.toLowerCase(); if(a== b) return 0; return a> b? 1:-1; } if(!L) return this.sort(alphaSort); this.sort(function(a, b){ var tem= 0, indx=0; while(tem==0 && indx 

Un bon moyen de sortinger de nombreux champs qui sont des chaînes est d’utiliser toLocaleCompare et l’opérateur booléen || .

Quelque chose comme:

 // Sorting record releases by name and then by title. releases.sort((oldRelease, newRelease) => { const compareName = oldRelease.name.localeCompare(newRelease.name); const compareTitle = oldRelease.title.localeCompare(newRelease.title); return compareName || compareTitle; }) 

Si vous voulez sortinger sur plus de champs, vous pouvez simplement les chaîner dans la déclaration de retour avec plus d’opérateurs booléens.

Vous pouvez concaténer les 2 variables ensemble dans une clé de sorting et l’utiliser pour votre comparaison.

 list.sort(function(a,b){ var aCat = a.var1 + a.var2; var bCat = b.var1 + b.var2; return (aCat > bCat ? 1 : aCat < bCat ? -1 : 0); }); 

Je suggère d’utiliser un comparateur intégré et d’enchaîner l’ordre de sorting souhaité avec logique ou || .

 function customSort(a, b) { return a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]); } 

Exemple de travail:

 var array = [ [0, 'Aluminium', 0, 'Francis'], [1, 'Argon', 1, 'Ada'], [2, 'Brom', 2, 'John'], [3, 'Cadmium', 3, 'Marie'], [4, 'Fluor', 3, 'Marie'], [5, 'Gold', 1, 'Ada'], [6, 'Kupfer', 4, 'Ines'], [7, 'Krypton', 4, 'Joe'], [8, 'Sauerstoff', 3, 'Marie'], [9, 'Zink', 5, 'Max'] ]; array.sort(function (a, b) { return a[3].localeCompare(b[3]) || a[1].localeCompare(b[1]); }); document.write('
'); array.forEach(function (a) { document.write(JSON.ssortingngify(a) + '
'); });

Je travaillais avec ng-grid et je devais sortinger plusieurs colonnes sur un tableau d’enregistrements renvoyés par une API. J’ai donc trouvé cette fonction multi-sorting dynamic et astucieuse.

Tout d’abord, ng-grid déclenche un “événement” pour “ngGridSorted” et renvoie cette structure en décrivant le sorting:

 sortData = { columns: DOM Element, directions: [], //Array of ssortingng values desc or asc. Each index relating to the same index of fields fields: [], //Array of ssortingng values }; 

Donc, j’ai construit une fonction qui va générer dynamicment une fonction de sorting basée sur le sortData comme montré ci-dessus ( Ne soyez pas effrayé par la barre de défilement! Il ne fait que 50 lignes environ! Aussi, je suis désolé pour le slop. barre de défilement horizontale! ):

 function SortingFunction(sortData) { this.sortData = sortData; this.sort = function(a, b) { var retval = 0; if(this.sortData.fields.length) { var i = 0; /* Determine if there is a column that both entities (a and b) have that are not exactly equal. The first one that we find will be the column we sort on. If a valid column is not located, then we will return 0 (equal). */ while( ( !a.hasOwnProperty(this.sortData.fields[i]) || !b.hasOwnProperty(this.sortData.fields[i]) || (a.hasOwnProperty(this.sortData.fields[i]) && b.hasOwnProperty(this.sortData.fields[i]) && a[this.sortData.fields[i]] === b[this.sortData.fields[i]]) ) && i < this.sortData.fields.length){ i++; } if(i < this.sortData.fields.length) { /* A valid column was located for both entities in the SortData. Now perform the sort. */ if(this.sortData.directions && i < this.sortData.directions.length && this.sortData.directions[i] === 'desc') { if(a[this.sortData.fields[i]] > b[this.sortData.fields[i]]) retval = -1; else if(a[this.sortData.fields[i]] < b[this.sortData.fields[i]]) retval = 1; } else { if(a[this.sortData.fields[i]] < b[this.sortData.fields[i]]) retval = -1; else if(a[this.sortData.fields[i]] > b[this.sortData.fields[i]]) retval = 1; } } } return retval; }.bind(this); } 

Je sortinge ensuite les résultats de mon API ( results ) comme suit:

 results.sort(new SortingFunction(sortData).sort); 

J’espère que quelqu’un d’autre aime cette solution autant que moi! Merci!

J’ai trouvé multisotr . C’est une bibliothèque simple, puissante et petite pour le sorting multiple. J’avais besoin de sortinger un tableau d’objects avec des critères de sorting dynamics:

 const criteria = ['name', 'speciality'] const data = [ { name: 'Mike', speciality: 'JS', age: 22 }, { name: 'Tom', speciality: 'Java', age: 30 }, { name: 'Mike', speciality: 'PHP', age: 40 }, { name: 'Abby', speciality: 'Design', age: 20 }, ] const sorted = multisort(data, criteria) console.log(sorted) 
  
 function multiSort() { var args =$.makeArray( arguments ), sortOrder=1, prop='', aa='', b=''; return function (a, b) { for (var i=0; i bb) return 1 * sortOrder; } return 0 } } empArray.sort(multiSort( 'lastname','firstname')) Reverse with '-lastname'