Javascript: Ordenar arreglos de objetos por sus propiedades

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?

Anuncios

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(sa<sb?-1:sa>sb?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(c<d?-1:c>d?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})}

Autor: Israel Muñoz

Soy desarrollador de software, principalmente dedicado a desarrollo de aplicaciones web. Especializado en .NET full-stack, además de tecnologías front-end HTML, CSS y JavaScript. A ratos, profesor de materias de informática. Me gusta mucho todo lo que tiene que ver con las tecnologías nuevas para desarrollo web, y el diseño de sitios y aplicaciones.

4 comentarios en “Javascript: Ordenar arreglos de objetos por sus propiedades”

  1. 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.

  2. 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 🙂

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s