2011-01-02 5 views
32

¿Cómo ordenaría estos datos por count y year valores en orden ascendente priorizando en el valor count?Ordenar por dos valores priorizando en uno de ellos

//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' }, 
]; 

Respuesta

41

(See the jsfiddle)

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

    return x.year - y.year; 
}); 
+15

one-liner 'data.sort (function (x, y) {return x.count - y.count || x.year - y.year;});' –

+0

@LucaSteeb su solución funcionó como un campeón y salvó mi día –

+1

@cdhowie tienes razón, de hecho necesito entender mejor cómo funcionan los algoritmos de clasificación. Eliminaré mis comentarios, gracias. –

12

Puede utilizar el método de JavaScript .sort() array (try it out):

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; 
}); 

Nota: Esto cambia la matriz original. Si necesita hacer una copia en primer lugar, puede hacerlo:

var dataCopy = data.slice(0); 
+0

comprobar mi one-liner en la pregunta anterior –

5

que tiene que trabajar a cabo este problema como este camino

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; 
     } 
    }; 

};

e.g: data.sort (customSort ('year', customSort ('count')));

+0

esa función me ayuda mucho: D –

+0

después de todo sh! T; esto finalmente funciona: D thx. – mayankcpdixit

+0

un reverso opcional sería increíble tener aquí. – mayankcpdixit

27

Una solución sencilla es:

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

Esto funciona porque si recuento es diferente, entonces el tipo se basa en eso. Si cuenta es lo mismo, la primera expresión devuelve 0 que convierte a falso y se utiliza el resultado de la segunda expresión (es decir, el género se basa en año).

+1

¡Buen uso de 0 como falsey! –

+0

Versión ES: data.sort ((a, b) => (a.count - b.count || a.year - b.year)); –

1

usuario esta en el 'recuento' -> primera prioridad y 'años' -> segunda prioridad

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

Basado en gran @RobG simple solution, he creado una función para ordenar por múltiples propiedades diferentes, usando un JS2015 difícil en map + find:

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

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

Además, si se prefiere, una versión tradicional JS (usar con precaución debido a find compatibility en los navegadores antiguos):

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; 
    }); 
    }); 
}; 
1

Si está buscando ordenar cadenas en orden alfabético en lugar de números, aquí hay un problema de muestra y su solución.

Ejemplo Problema: matriz de matrices (finalArray) con la primera entrada de una ruta de la carpeta y segunda entrada el nombre de archivo; ordene para que la matriz esté organizada por carpeta primero, y dentro de carpetas idénticas, por nombre de archivo.

E.g.después de la clasificación que espera:

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

Consulte 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; 
    } 
}); 

Tenga en cuenta, "Z" viene antes de "a" (mayúsculas en primer lugar según punto de código Unicode) que es por eso que tengo toLowerCase(). El problema que la implementación anterior no resuelve es que "10abc" vendrá antes que "9abc".

Cuestiones relacionadas