El tipo Array de javascript incluye una función sort
para ordenar los elementos del arreglo. Podemos ordenar arreglos numéricos, de texto, de fechas, etc. Pero ¿cómo ordenamos un arreglo de objetos por una propiedad específica?
Este artículo está basado en este otro de JavaScript Kit: Sorting an array of objects.
La función sort del tipo Array recibe como parámetro a otra función. Esta función recibe a su vez dos parámetros, que son dos elementos en el arreglo que serán comparados entre sí, y devuelve como resultado un número positivo o negativo, dependiendo si el primer parámetro va después o antes del segundo. Esta función es ejecutada para todos los elementos del arreglo entre sí hasta que quede ordenado.
Con base en esto, podemos extender el objeto Array para incluir las funciones de ordenamiento por tipo de dato:
/*! Ordenar elementos del arreglo por una propiedad numérica. */ Array.prototype.orderByNumber=function(property,sortOrder){ // Primero se verifica que la propiedad sortOrder tenga un dato válido. if (sortOrder!=-1 && sortOrder!=1) sortOrder=1; this.sort(function(a,b){ // La función de ordenamiento devuelve la comparación entre property de a y b. // El resultado será afectado por sortOrder. return (a[property]-b[property])*sortOrder; }) } /*! Ordenar elementos del arreglo por una propiedad de tipo String */ Array.prototype.orderByString=function(property,sortOrder,ignoreCase){ if (sortOrder!=-1 && sortOrder!=1) sortOrder=1; this.sort(function(a,b){ var stringA=a[property],stringB=b[property]; // Si un valor es null o undefined, se convierte a cadena vacía. if (stringA==null) stringA = ''; if (stringB==null) stringB = ''; // Si ignoreCase es true, se convierten ambas variables a minúsculas. if (ignoreCase==true){stringA=stringA.toLowerCase();stringB=stringB.toLowerCase()} var res = 0; if (stringA<stringB) res = -1; else if (stringA>stringB) res = 1; return res*sortOrder; }) } /*! Ordenar elementos de arreglo */ Array.prototype.orderByDate=function(property,sortOrder){ if (sortOrder!=-1 && sortOrder!=1) sortOrder=1; this.sort(function(a,b){ var dateA=new Date(a[property]),dateB=new Date(b[property]); return (dateA-dateB)*sortOrder; }) }
Cada tipo de dato tiene sus particularidades, por eso creé tres funciones. Al ordenar cadenas de texto, por ejemplo, Javascript pone primero las palabras con mayúsculas y después con minúsculas. Para eso es el parámetro ignoreCase.
Con esto podemos ordenar un arreglo de objetos segun una de sus propiedades.
var arreglo=[ {id:1,nombre:'Juan',fechaNacimiento:new Date(1982,10,5)}, {id:2,nombre:'María',fechaNacimiento:new Date(1991,3,26)}, {id:3,nombre:'Pedro',fechaNacimiento:new Date(1980,6,10)} ]; arreglo.orderByNumber('id',-1); alert(arreglo[0].nombre); // Devuelve "Pedro" arreglo.orderByString('nombre'); alert(arreglo[0].nombre); // Devuelve "Juan" arreglo.orderByDate('fechaNacimiento',-1); alert(arreglo[0].nombre); // Devuelve "María"
Versión reducida
Si prefieren una versión menos comentada, eliminando espacios innecesarios y ahorrando operaciones, aquí está el mismo código en una versión más reducida.
/*! Ordenar elementos del arreglo por una propiedad numérica. */ Array.prototype.orderByNumber=function(p,so){ if(so!=-1&&so!=1)so=1; this.sort(function(a,b){ return(a[p]-b[p])*so; }) } /*! Ordenar elementos del arreglo por una propiedad de tipo String */ Array.prototype.orderByString=function(p,so,ic){ if(so!=-1&&so!=1)so=1; this.sort(function(a,b){ var sa=a[p]!=null?a[p].toString():'',sb=b[p]!=null?b[p].toString():''; if(ic==true){sa=sa.toLowerCase();sb=sb.toLowerCase()} return(sasb?1:0)*so; }) } /*! Ordenar elementos de arreglo */ Array.prototype.orderByDate=function(p,so){ if(so!=-1&&so!=1)so=1; this.sort(function(a,b){ var da=new Date(a[p]),db=new Date(b[p]); return(da-db)*so; }) }
Versión comprimida
Ya si de plano quieren el código lo más reducido posible, aquí está la versión ultra-comprimida:
/*! Ordenamiento de arreglos de objetos por el valor de una propiedad. Autor: Israel Muñoz https://deployando.net/ */ Array.prototype.orderByNumber=function(p,s){if(s!=-1&&s!=1)s=1;this.sort(function(a,b){return(a[p]-b[p])*s})} Array.prototype.orderByString=function(p,s,i){if(s!=-1&&s!=1)s=1;this.sort(function(a,b){var c=a[p]!=null?a[p].toString():'',d=b[p]!=null?b[p].toString():'';if(i==true){c=c.toLowerCase();d=d.toLowerCase()}return(cd?1:0)*s})} Array.prototype.orderByDate=function(p,s){if(s!=-1&&s!=1)s=1;this.sort(function(a,b){var c=new Date(a[p]),d=new Date(b[p]);return(c-d)*s})}
no sirve.
Dime en qué navegador no te funcionó y tratemos de hacerlo funcionar o encontrarle alternativa.
Hola, estoy desarrollando una App movil para smartphones Firefox Os. Estoy leyendo un Json de un webservice con un itinerario de pasajes, lleno una lista con cada conteniendo nombre empresa transporte, hora salida, hora llegada, precio,etc. La idea es tener un array conteniendo en cada indice las propiedades antes mencionadas, y poder ordenarlas de acuerdo a lo que quiera el usuario: ordenar por precio de menor a mayor, o por hora salida. de Igual manera agrupar por nombre de empresa alfabeticamente (todos los pasajes de empresa «A» juntos, luego los de «B», etc). Podrias ayudarme en eso? saludos.
Estimado, es una tremenda obra de arte en cuanto a Script. Felicitaciones A octubre de 2018 funciona a la perfección en todos los navegadores. Ademas esta explicado de forma clara y precisa
Muchas Gracias 🙂
muchas gracias por el ejemplo, no me había dado cuenta del uso de los parametros de sort(), gracias a tu ejemplo me pude guiar ya que en mi caso los objetos que estaban dentro del array todos tenian 1 sola propiedad y de nombre diferente, asi que me sirvio de esta manera:
arrObjects.sort( (a,b) => a[Object.keys(a)] – b[Object.keys(b)]);
gracias .