Cómo ordenar un array numérico en JavaScript

3054927-inline-s-3-microsofts-inclusive-design

Cada vez me gusta más usar las funciones que llevan implementadas los array por defecto en JavaScript. Me gusta como el código queda mucho más explicativo cuando se usan funciones para manipular arrays en vez de ir iterando una colección cada vez que necesito realizar una acción.

Desde que EcmaScript 5 se instauró en todos los navegadores, usar las funciones map, filter o each me ayudan a hacer mi código mucho más expresivo y a usar JavaScript de una forma más declarativa.

El problema viene cuando alguna de las funciones que hay implementadas no cumplen con lo que nosotros creemos que debería hacer. Un caso muy común (y que a mi me ha pasado) es a la hora de tener que ordenar una colección de enteros y se nos ocurre hacerlo con la función sort. Es aquí cuando podemos cometer un error por culpa de no entender la especificación del lenguaje.

Imaginemos que tenemos que ordenar la siguiente colección de enteros:

[101, 1, 2, 1001].sort()

Lo que nosotros esperamos que nos devuelva sort es lo siguiente:

[1, 2, 101, 1001]

Sin embargo, si ejecutamos el código en la consola obtenemos esto:

[1, 1001, 101, 2]

¿Qué ha pasado? ¿Se nos ha roto el JS? Parece que no, parece más un mal diseño de la función o un nombre poco afortunado de lo que debería hacer la función. Si leemos la especificación el comportamiento es el esperado:

El métodosort()ordena los elementos de un array localmente y retorna el array. Si no se provee de una función de comparación, los elementos son ordenados convirtiéndolos a strings y comparando la posición del valor Unicode de dichos strings.

Y es aquí donde llega el problema. El array anterior es convertido a strings y comparados por su valor Unicode. Los valores Unicode de “101” y el de “1001” son menores que el de “2” de ahí que no se cumpla la ordenación de enteros.

Pero esto no se queda aquí, ya que podríamos esperar que, aunque para colecciones numéricas se comporte mal, para colecciones de cadenas pueda llegar a sernos útil. Si evaluamos la siguiente colección:

['arbol', 'Rama', 'fruto'].sort()

Nosotros esperaríamos esto:

['arbol', 'fruto', 'Rama']

Y en realidad JavaScript hace esto:

['Rama', 'arbol', 'fruto']

Seguimos con el mismo problema. Como JavaScript ordena a partir de los valores Unicode, las mayúscula en Unicode se encuentran antes que las minúsculas por lo que tendremos que tener cuidado a la hora de ordenar por formato cadena.

¿Y entonces cómo podemos ordenar en JavaScript? Bueno, una forma bastante sencilla es no dejar la ordenación por defecto de sort, sino usar una función que realice la evaluación. De la siguiente forma obtendríamos el resultado esperado:

[101, 1, 2, 1001].sort((a, b) => a - b);

Con esa pequeña lambda lo solucionamos.

Espero que os haya sido de utilidad y recordad que nada en JavaScript es obvio.

Nos leemos 🙂

Imagen de portada | Fastcodesign

Anuncios

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 )

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 )

Google+ photo

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

Conectando a %s