web-dev-qa-db-fra.com

Trier par deux valeurs donnant la priorité à l'une d'elles

Comment pourrais-je trier ces données par les valeurs count et year dans l'ordre croissant, en donnant la priorité à la valeur count

//sort this
var data = [
    { count: '12', year: '1956' },
    { count: '1', year: '1971' },
    { count: '33', year: '1989' },
    { count: '33', year: '1988' }
];
//to get this
var data = [
    { count: '1', year: '1971' },
    { count: '12', year: '1956' },
    { count: '33', year: '1988' },
    { count: '33', year: '1989' },
];
41
Dojie

( Voir le jsfiddle )

data.sort(function (x, y) {
    var n = x.count - y.count;
    if (n !== 0) {
        return n;
    }

    return x.year - y.year;
});
57
cdhowie

Une solution simple est:

data.sort(function (a, b) {
  return a.count - b.count || a.year - b.year;
});

Cela fonctionne parce que si count est différent, le tri est basé sur cela. Si count est identique, la première expression renvoie 0 qui est converti en false et le résultat de la seconde expression est utilisé (le tri est basé sur year ).

42
RobG

Vous pouvez utiliser la méthode .sort() array de JavaScript ( essayez-le ):

data.sort(function(a, b) {
    // Sort by count
    var dCount = a.count - b.count;
    if(dCount) return dCount;

    // If there is a tie, sort by year
    var dYear = a.year - b.year;
    return dYear;
});

Remarque: Cela modifie le tableau d'origine. Si vous devez d'abord en faire une copie, vous pouvez le faire:

var dataCopy = data.slice(0);
13
PleaseStand

vous devez résoudre ce problème de cette façon 

var customSort = function(name, type){
     return function(o, p){
         var a, b;
         if(o && p && typeof o === 'object' && typeof p === 'object'){
            a = o[name];
            b = p[name];
           if(a === b){
              return typeof type === 'function' ? type(o, p) : o;
           }

           if(typeof a=== typeof b){
              return a < b ? -1 : 1;
            }
          return typeof a < typeof b ? -1 : 1;
        }
     };

};

par exemple : data.sort (customSort ('year', customSort ('count'))); 

6
paul

Basée sur l'excellente @RobG solution , il s'agit d'une fonction générique permettant de trier selon plusieurs propriétés différentes, à l'aide d'une astuce JS2015 sur map + find:

let sortBy = (p, a) => a.sort((i, j) => p.map(v => i[v] - j[v]).find(r => r))

sortBy(['count', 'year'], data)

De plus, si vous préférez, une version JS traditionnelle (à utiliser avec prudence en raison de trouver la compatibilité dans les anciens navigateurs):

var sortBy = function (properties, targetArray) {
  targetArray.sort(function (i, j) {
    return properties.map(function (prop) {
      return i[prop] - j[prop];
    }).find(function (result) {
      return result;
    });
  });
};
6
19WAS85

Si vous cherchez à trier strings dans l'ordre alphabétique plutôt que dans les nombres, voici un exemple de problème et sa solution.

Exemple de problème: Tableau de tableaux (finalArray) avec la première entrée un chemin de dossier et la deuxième entrée le nom de fichier; triez-le de manière à ce que le tableau soit d'abord classé par dossier, puis dans des dossiers identiques, par nom de fichier.

Par exemple. après le tri, vous attendez:

[['folder1', 'abc.jpg'], 
 ['folder1', 'xyz.jpg'],
 ['folder2', 'def.jpg'],
 ['folder2', 'pqr.jpg']]

Reportez-vous à Array.prototype.sort () - compareFunction

finalArray.sort((x: any, y: any): number => {
  const folder1: string = x[0].toLowerCase();
  const folder2: string = y[0].toLowerCase();
  const file1: string = x[1].toLowerCase();
  const file2: string = y[1].toLowerCase();

  if (folder1 > folder2) {
    return 1;
  } else if (folder1 === folder2 && file1 > file2) {
    return 1;
  } else if (folder1 === folder2 && file1 === file2) {
    return 0;
  } else if (folder1 === folder2 && file1 < file2) {
    return -1;
  } else if (folder1 < folder2) {
    return -1;
  }
});

Gardez à l'esprit que "Z" vient avant "a" (les capitales d'abord en fonction de point de code Unicode), raison pour laquelle j'ai toLowerCase (). Le problème que l'implémentation ci-dessus ne résout pas, c'est que "10abc" viendra avant "9abc".

1
Boris Yakubchik

user this où 'count' -> première priorité et 'year' -> seconde priorité

data.sort(function(a,b){
  return a['count']<b['count']?-1:(a['count']>b['count']?1:(a['year']<b['year']?-1:1));
});
1
abs