Cómo ordenar una matriz de enteros correctamente


849

Intentar obtener el valor más alto y más bajo de una matriz que sé que contendrá solo enteros parece ser más difícil de lo que pensaba.

var numArray = [140000, 104, 99];
numArray = numArray.sort();
alert(numArray)

Esperaría que esto se notara 99, 104, 140000. En cambio se nota 104, 140000, 99. Entonces parece que el tipo está manejando los valores como cadenas.

¿Hay alguna manera de obtener la función de ordenación para realmente ordenar el valor entero?


10
Observe que ninguna de las respuestas principales trata con todos los valores de punto flotante correctamente; en particular, ninguno de ellos maneja NaN. Sería bueno ver una respuesta altamente calificada con la que lidiar NaN.
Quuxplusone

3
Por cierto, si está ordenando montones y montones de enteros, será ventajoso utilizar un algoritmo de ordenación de enteros como contar . El orden de conteo de tiempo tomará ejecutar escalas linealmente con el tamaño de su matriz: O (n). Mientras que todas las soluciones aquí usan un tipo de comparación que es menos eficiente: O (n * log n).
Web_Designer

1
@Web_Designer La ordenación de conteo es lineal con respecto al rango de números, no a la matriz. Por ejemplo, la clasificación [1,1000000] tomará más de 2 pasos, ya que el algoritmo tendrá que escanear cada índice de matriz entre 1 y 1000000 para ver qué valor de celda es mayor que 0.
años

2
@yters Usando un hashmap, solo puede prestar atención a los enteros que aparecen en la matriz que se está ordenando. Esto hace que la ordenación lineal sea el tamaño de la matriz.
Kevin

1
la forma más rápida es utilizar el módulo de ordenamiento isomorfo que funciona de forma nativa tanto en el navegador como en el nodo, que admite cualquier tipo de entrada, campos calculados y órdenes de clasificación personalizadas.
Lloyd

Respuestas:


1236

Por defecto, el método de clasificación ordena los elementos alfabéticamente. Para ordenar numéricamente solo agregue un nuevo método que maneje los ordenamientos numéricos (sortNumber, que se muestra a continuación):

var numArray = [140000, 104, 99];
numArray.sort(function(a, b) {
  return a - b;
});

console.log(numArray);

En ES6, puede simplificar esto con las funciones de flecha:

numArray.sort((a, b) => a - b); // For ascending sort
numArray.sort((a, b) => b - a); // For descending sort

Documentación:

Mozilla Array.prototype.sort()recomienda esta función de comparación para matrices que no contienen Infinity o NaN. (Porque Inf - Infes NaN, no 0).

También ejemplos de ordenar objetos por clave.


149
Agradable. Pero, ¿realmente no hay una forma inmediata de obtener una ordenación numérica de JavaScript?
peirix

39
ahah esto está fuera de la caja! Pero si no es práctico, puede vincular funciones a la clase de clase de matriz al comienzo de su javascript: // Array.prototype.sortNormal = function () {return this.sort (function (a, b) {return a - b})} // Ahora llamando a .sortNormal () en cualquier matriz lo ordenará numéricamente
Jack Franzen

13
¿Por qué ab y no a> b. Sugiero el último para evitar errores de operación de la máquina
Luca Davanzo

35
@Velthune La función de comparación debería devolver -1, 0 o +1. a> b solo devolverá verdadero o falso.
Iván Pérez

48
Este código se puede acortar usando una función de flecha . numberArray.sort((a, b) => (a - b));¡Hurra! Creo que esto está cerca de la forma original. Nota: compruebe si su motor JS admite funciones de flecha.
Константин Ван

174

Basándose en todas las respuestas anteriores, también se pueden hacer en una línea como esta:

var numArray = [140000, 104, 99];

// ES5
numArray = numArray.sort(function (a, b) {  return a - b;  });

// ES2015
numArray = numArray.sort((a, b) => a - b);

//outputs: 99, 104, 140000

8
@bodyflex fijo: var arr = [140000, 104, 99].sort(function(a,b) { return a-b; });. O más compacto, en ES6let arr = [140000, 104, 99].sort((a,b) => a-b);
00500005

1
Como dije en un comentario anterior, las funciones de flecha encajan mal aquí y desalentaría a cualquiera de usarlas de esta manera. Está utilizando un efecto secundario de la sintaxis de flecha para cortar las palabras functiony return, pero en realidad no está utilizando el verdadero propósito de pasar de la función de flecha this. Este código implica que está thispasando algún contexto, pero no lo hay. Confuso para que otros desarrolladores lean su código, solo para guardar algunos caracteres. No dependa de los efectos secundarios: ¡codifique con un propósito!
bambery

12
@bambery No creo que necesite usar una función de flecha exclusivamente para cambios de contexto ...
Ted Morin

77
@bambery, realmente no entiendes lo que está haciendo la función de flecha. Crees que de alguna manera pasa thisa la función, pero eso no es cierto. De hecho, se olvida de crear ay thisla argumentsvariable que generalmente sobrescribe las variables principales. La única razón por la que puede usar thisdentro de una función de flecha es el alcance léxico.
cuth

2
@bambery que no envejeció bien ... tres años después y el desarrollo moderno de JavaScript utiliza funciones de flecha casi exclusivamente. :)
Kip

71

array.sort realiza una ordenación lexicográfica por defecto, para una ordenación numérica, proporciona su propia función. Aquí hay un ejemplo simple:

function compareNumbers(a, b)
{
    return a - b;
}

numArray.sort(compareNumbers);

También tenga en cuenta que la ordenación funciona "en el lugar", no hay necesidad de la asignación.


No entendí el código anterior, ¿cómo "devuelve a - b" hace la clasificación ascendente?
vikramvi

si a <b, compareNumbers devuelve un número negativo. Si a> b, será positivo. Si es igual, devuelve 0.
Paul Dixon

38

Esta respuesta es equivalente a algunas de las respuestas existentes, pero las funciones de flecha de ECMAScript 6 proporcionan una sintaxis mucho más compacta que nos permite definir una función de clasificación en línea sin sacrificar la legibilidad:

numArray = numArray.sort((a, b) => a - b);

Actualmente es compatible con la mayoría de los navegadores .


1
"sin sacrificar la legibilidad". Esto es subjetivo. Con algunos enteros simples es legible. Al trabajar con objetos más complejos y desea ordenar por una propiedad, no tanto.
Tristan

3
@Tristan, la clasificación de una propiedad de un objeto todavía se puede hacer de manera bastante limpia usando esta sintaxis. Si la propiedad del objeto que desea ordenar es un número que puede hacer: objArray=objArray.sort((a,b)=>a.numProperty - b.numProperty);y si la propiedad es una cadena, puede hacerlo: objArray=objArray.sort((a,b)=>a.strProperty.localeCompare(b.strProperty))‌​;Dicho esto, esta pregunta específicamente pregunta sobre la ordenación de una matriz de enteros
jjjjs

34

Estoy sorprendido de por qué todos recomiendan pasar una función de comparación sort(), ¡eso hace que la clasificación sea muy lenta!

Para ordenar los números, simplemente cree cualquier TypedArray :

var numArray = new Uint32Array([140000, 104, 99]);
numArray = numArray.sort();
alert(numArray)


44
El uso de un TypedArray acelera la clasificación en aproximadamente 5X. Si desea ir aún más rápido, el paquete hpm de algoritmos hpc implementa la clasificación por radix y la clasificación por conteo que varias respuestas sugieren aquí.
DragonSpit

wow, ¡no sabía que esto existía!
pixelearth

21

La razón por la cual la función de clasificación se comporta tan raro

De la documentación :

[...] la matriz se ordena según el valor de punto de código Unicode de cada carácter, según la conversión de cadena de cada elemento.

Si imprime los valores de punto unicode de la matriz, se aclarará.

console.log("140000".charCodeAt(0));
console.log("104".charCodeAt(0));
console.log("99".charCodeAt(0));

//Note that we only look at the first index of the number "charCodeAt(  0  )"

Esto devuelve: "49, 49, 57".

49 (unicode value of first number at 140000)
49 (unicode value of first number at 104)
57 (unicode value of first number at 99)

Ahora, debido a que 140000 y 104 devolvieron los mismos valores (49), corta el primer índice y vuelve a verificar:

console.log("40000".charCodeAt(0));
console.log("04".charCodeAt(0));

//Note that we only look at the first index of the number "charCodeAt(  0  )"

52 (unicode value of first number at 40000)
40 (unicode value of first number at 04)

Si clasificamos esto, obtendremos:

40 (unicode value of first number at 04)
52 (unicode value of first number at 40000)

entonces 104 viene antes de 140000.

Entonces el resultado final será:

var numArray = [140000, 104, 99];
numArray = numArray.sort();
console.log(numArray)

104, 140000, 99

Conclusión:

sort()ordena solo mirando el primer índice de los números. sort()no le importa si un número entero es más grande que otro, compara el valor del unicode de los dígitos, y si hay dos valores unicode iguales, comprueba si hay un siguiente dígito y también lo compara.

Para ordenar correctamente, debe pasar una función de comparación a sort()Me gusta explicada aquí .


Sugerencia: Esta es solo mi explicación, en realidad no busqué el código. Así que no confíes completamente en esta respuesta.
Negro

17

Estoy de acuerdo con aks, sin embargo, en lugar de usar

return a - b;

Deberías usar

return a > b ? 1 : a < b ? -1 : 0;

18
¿Puede explicar por qué alguien debería usar su operación ternaria más ilegible? Por lo que puedo decir, tendría el mismo resultado.
stefannew

66
Esta respuesta también toma en consideración valores iguales y los deja en el mismo lugar.
Maarten00

23
¿Y a - b no?
Bryan Rayner

12
"return ab" puede ser adecuado para el caso particular de esta pregunta (javascript y todos los elementos de entrada conocidos como ints), pero personalmente prefiero la forma ternaria porque es más canónica: funciona en más casos, en más lenguajes de programación , con más tipos de datos. Por ejemplo, en C, ab puede desbordarse, lo que lleva al tipo de bucles sin fin, corrompe la memoria, bloquea, etc. Dicho esto, incluso la forma ternaria no funcionará de manera sensata si hay NaN o tipos mixtos involucrados.
Don Hatch

8
El >y <todavía compara a y b como cadenas.
vriesdemichael

11

En el nuevo mundo ES6 es mucho más fácil hacer una especie

numArray.sort((a,b) => a-b);

Eso es todo lo que necesitas :)


10

En JavaScript, el comportamiento predeterminado del método sort () es ordenar los valores en una matriz alfabéticamente.

Para ordenar por número, debe definir una función de clasificación numérica (que es muy fácil):

...
function sortNumber(a, b)
{
  return a - b;
}

numArray = numArray.sort(sortNumber);

8

Array.prototype.sort () es el método de ir a la ordenación de matrices, pero hay algunos problemas que debemos tener en cuenta.

El orden de clasificación es, por defecto, lexicográfico y no numérico, independientemente de los tipos de valores en la matriz. Incluso si la matriz es todos los números, todos los valores se convertirán en cadenas y se ordenarán lexicográficamente.

Entonces, ¿deberíamos personalizar el método sort () y reverse () como se muestra a continuación.

URL referida

Para ordenar números dentro de la matriz

numArray.sort(function(a, b)
{
    return a - b;
});

Para invertir números dentro de la matriz

numArray.sort(function(a, b)
{
    return b - a;
});

URL referida


6

La pregunta ya ha sido respondida, la forma más corta es utilizar el sort()método. Pero si está buscando más formas de ordenar su conjunto de números, y también le encantan los ciclos, consulte lo siguiente

Tipo de inserción

Ascendente:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length; i++) {
    var target = numArray[i];
    for (var j = i - 1; j >= 0 && (numArray[j] > target); j--) {
        numArray[j+1] = numArray[j];
    }
    numArray[j+1] = target
}
console.log(numArray);

Descendente:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length; i++) {
    var target = numArray[i];
    for (var j = i - 1; j >= 0 && (numArray[j] < target); j--) {
        numArray[j+1] = numArray[j];
    }
    numArray[j+1] = target
}
console.log(numArray);

Tipo de selección:

Ascendente:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length - 1; i++) {
    var min = i;
    for (var j = i + 1; j < numArray.length; j++) {
        if (numArray[j] < numArray[min]) {
            min = j;
        }
    }
    if (min != i) {
        var target = numArray[i];
        numArray[i] = numArray[min];
        numArray[min] = target;
    }
}
console.log(numArray);

Descendente:

var numArray = [140000, 104, 99];
for (var i = 0; i < numArray.length - 1; i++) {
    var min = i;
    for (var j = i + 1; j < numArray.length; j++) {
        if (numArray[j] > numArray[min]) {
            min = j;
        }
    }
    if (min != i) {
        var target = numArray[i];
        numArray[i] = numArray[min];
        numArray[min] = target;
    }
}
console.log(numArray);

Que te diviertas


¿ Alguno de estos es realmente más rápido para arreglos pequeños que usarlo sort()en un TypedArray como sugiere esta respuesta ? Ciertamente no serán más rápidos para matrices medianas a grandes porque estos son algoritmos O (n ^ 2).
Peter Cordes el

5

La función 'numéricamente' a continuación sirve para ordenar una matriz de números numéricamente en muchos casos cuando se proporciona como una función de devolución de llamada:

function numerically(a, b){
    return a-b;
}

array.sort(numerically); 

Pero en algunos casos raros, donde la matriz contiene números muy grandes y negativos, puede ocurrir un error de desbordamiento debido a que ab se vuelve más pequeño que el número más pequeño que JavaScript puede manejar.

Entonces, una mejor manera de escribir la función numérica es la siguiente:

function numerically(a, b){
   if(a < b){
      return -1;
   } else if(a > b){
      return 1;
   } else {
      return 0;
   }
}

1
Los números de JavaScript son de coma flotante. IEEE754 define las reglas de desbordamiento y subflujo, incluido el desbordamiento a + -Infinito y el subflujo a subnormal o + -0.0. No creo que la resta de dos números pueda pasar a + -0.0, incluso si ambos son grandes y cercanos. La diferencia entre dos dobles siempre es representable como otro doble distinto de cero (a menos que se desborde, como DBL_MIN - DBL_MAX), pero no es posible el subflujo. La cancelación catastrófica hace que el resultado sea impreciso, perdiendo la mayoría de sus "dígitos significativos", pero a-bsiempre será distinto de cero y tendrá el signo correcto para a! = B.
Peter Cordes el

4

para manejar undefined, null y NaN: Null se comporta como 0, NaN y undefined va al final.

array = [3, 5, -1, 1, NaN, 6, undefined, 2, null]
array.sort((a,b) => isNaN(a) || a-b)
// [-1, null, 1, 2, 3, 5, 6, NaN, undefined]

3

Solo para una matriz normal de valores de elementos:

function sortArrayOfElements(arrayToSort) {
    function compareElements(a, b) {
        if (a < b)
            return -1;
        if (a > b)
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareElements);
}

e.g. 1:
var array1 = [1,2,545,676,64,2,24]
**output : [1, 2, 2, 24, 64, 545, 676]**

var array2 = ["v","a",545,676,64,2,"24"]
**output: ["a", "v", 2, "24", 64, 545, 676]**

Para una matriz de objetos:

function sortArrayOfObjects(arrayToSort, key) {
    function compareObjects(a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareObjects);
}

e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]

**output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]**

2

¡Actualizar! Desplácese hasta la parte inferior de la respuesta para el smartSortaditivo de accesorios que le da aún más diversión.
Ordena arreglos de cualquier cosa !

Mi forma favorita personal de esta función permite un parámetro para Ascendente o Descendente:

function intArraySort(c, a) {
    function d(a, b) { return b - a; }
    "string" == typeof a && a.toLowerCase();
    switch (a) {
        default: return c.sort(function(a, b) { return a - b; });
        case 1:
                case "d":
                case "dc":
                case "desc":
                return c.sort(d)
    }
};

Uso tan simple como:

var ara = function getArray() {
        var a = Math.floor(Math.random()*50)+1, b = [];
        for (i=0;i<=a;i++) b.push(Math.floor(Math.random()*50)+1);
        return b;
    }();

//    Ascending
intArraySort(ara);
console.log(ara);

//    Descending
intArraySort(ara, 1);
console.log(ara);

//    Ascending
intArraySort(ara, 'a');
console.log(ara);

//    Descending
intArraySort(ara, 'dc');
console.log(ara);

//    Ascending
intArraySort(ara, 'asc');
console.log(ara);

jsFiddle


O ejemplo de fragmento de código aquí!

function intArraySort(c, a) {
	function d(a, b) { return b - a }
	"string" == typeof a && a.toLowerCase();
	switch (a) {
		default: return c.sort(function(a, b) { return a - b });
		case 1:
		case "d":
		case "dc":
		case "desc":
		return c.sort(d)
	}
};

function tableExample() {
	var d = function() {
			var a = Math.floor(50 * Math.random()) + 1,
				b = [];
			for (i = 0; i <= a; i++) b.push(Math.floor(50 * Math.random()) + 1);
			return b
		},
		a = function(a) {
			var b = $("<tr/>"),
				c = $("<th/>").prependTo(b);
			$("<td/>", {
				text: intArraySort(d(), a).join(", ")
			}).appendTo(b);
			switch (a) {
				case 1:
				case "d":
				case "dc":
				case "desc":
					c.addClass("desc").text("Descending");
					break;
				default:
					c.addClass("asc").text("Ascending")
			}
			return b
		};
	return $("tbody").empty().append(a(), a(1), a(), a(1), a(), a(1), a(), a(1), a(), a(1), a(), a(1))
};

tableExample();
table { border-collapse: collapse; }
th, td { border: 1px solid; padding: .25em .5em; vertical-align: top; }
.asc { color: red; }
.desc { color: blue }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<table><tbody></tbody></table>


.smartSort ('asc' | 'desc')

¡Ahora diviértete aún más con un método de clasificación que clasifica una matriz llena de múltiples elementos! Actualmente no cubre "asociativo" (también conocido como teclas de cadena), ¡pero cubre casi todo tipo de valor! No solo ordenará los valores múltiples asco en descconsecuencia, sino que también mantendrá una "posición" constante de "grupos" de valores. En otras palabras; las entradas siempre son primero, luego vienen las cadenas, luego las matrices (sí, ¡estoy haciendo esto multidimensional!), luego los objetos (sin filtro, elemento, fecha), y finalmente ¡indefinidos y nulos!

"¿Por qué?" usted pregunta. ¡Por qué no!

¡Ahora viene en 2 sabores! El primero de los cuales requiere navegadores más nuevos, ya que se utiliza Object.definePropertypara agregar el método al Array.protoypeobjeto. Esto permite la facilidad de natural de uso, tales como: myArray.smartSort('a'). Si necesita implementar para navegadores más antiguos, o simplemente no le gusta modificar Objetos nativos, desplácese hacia abajo hasta la versión Solo método .

/* begin */
/* KEY NOTE! Requires EcmaScript 5.1 (not compatible with older browsers) */
;;(function(){if(Object.defineProperty&&!Array.prototype.smartSort){var h=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return a-b;if(/^stringstring$/ig.test(e))return a>b;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.smartSort("a");b instanceof Array&&b.smartSort("a");if(a instanceof Date&&b instanceof Date)return a-b;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=e.concat(g).smartSort("a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=[a[c],b[c]].smartSort("a"),a[c]==d[0]?-1:1;var f=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("a");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=[a.id,b.id].smartSort("a"),a.id==e[0]?1:-1;e=[a.tagName, b.tagName].smartSort("a");return a.tagName==e[0]?1:-1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);e.concat(g).smartSort("a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=[a[d].id,b[f].id].smartSort("a"),a[d].id==c[0]?-1:1;c=[a[d].tagName,b[f].tagName].smartSort("d"); return a[d].tagName==c[0]?1:-1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=[a[d],b[f]].smartSort("a"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element||!a.hasOwnProperty(d))return-1;if(!b.hasOwnProperty(d))return 1}c=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]>g[1]},k=function(a,b){if(null== a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return b-a;if(/^stringstring$/ig.test(e))return b>a;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.smartSort("d");b instanceof Array&&b.smartSort("d");if(a instanceof Date&&b instanceof Date)return b-a;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=e.concat(g).smartSort("a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=[a[c],b[c]].smartSort("d"),a[c]==d[0]?-1:1;var f=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=[a.id,b.id].smartSort("d"),a.id==e[0]?-1:1;e=[a.tagName,b.tagName].smartSort("d");return a.tagName==e[0]?-1:1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);e.concat(g).smartSort("a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=[a[d].id,b[f].id].smartSort("d"),a[d].id==c[0]?-1:1;c=[a[d].tagName,b[f].tagName].smartSort("d");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=[a[d],b[f]].smartSort("d"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element)return-1;if(!a.hasOwnProperty(d))return 1;if(!b.hasOwnProperty(d))return-1}c=[a[Object.keys(a)[0]],b[Object.keys(b)[0]]].smartSort("d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]<g[1]};Object.defineProperty(Array.prototype,"smartSort",{value:function(){return arguments&& (!arguments.length||1==arguments.length&&/^a([sc]{2})?$|^d([esc]{3})?$/i.test(arguments[0]))?this.sort(!arguments.length||/^a([sc]{2})?$/i.test(arguments[0])?h:k):this.sort()}})}})();
/* end */

jsFiddle Array.prototype.smartSort ('asc | desc')


¡El uso es simple! Primero haz una serie loca como:

window.z = [ 'one', undefined, $('<span />'), 'two', null, 2, $('<div />', { id: 'Thing' }), $('<div />'), 4, $('<header />') ];
z.push(new Date('1/01/2011'));
z.push('three');
z.push(undefined);
z.push([ 'one', 'three', 'four' ]);
z.push([ 'one', 'three', 'five' ]);
z.push({ a: 'a', b: 'b' });
z.push({ name: 'bob', value: 'bill' });
z.push(new Date());
z.push({ john: 'jill', jack: 'june' });
z.push([ 'abc', 'def', [ 'abc', 'def', 'cba' ], [ 'cba', 'def', 'bca' ], 'cba' ]);
z.push([ 'cba', 'def', 'bca' ]);
z.push({ a: 'a', b: 'b', c: 'c' });
z.push({ a: 'a', b: 'b', c: 'd' });

¡Entonces simplemente ordénelo!

z.smartSort('asc'); // Ascending
z.smartSort('desc'); // Descending

Solo método

¡Igual que el anterior, excepto como un método simple!

/* begin */
/* KEY NOTE! Method `smartSort` is appended to native `window` for global use. If you'd prefer a more local scope, simple change `window.smartSort` to `var smartSort` and place inside your class/method */
window.smartSort=function(){if(arguments){var a,b,c;for(c in arguments)arguments[c]instanceof Array&&(a=arguments[c],void 0==b&&(b="a")),"string"==typeof arguments[c]&&(b=/^a([sc]{2})?$/i.test(arguments[c])?"a":"d");if(a instanceof Array)return a.sort("a"==b?smartSort.asc:smartSort.desc)}return this.sort()};smartSort.asc=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return a-b;if(/^stringstring$/ig.test(e))return a> b;if(/(string|number){2}/ig.test(e))return/string/i.test(c)?1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.sort(smartSort.asc);b instanceof Array&&b.sort(smartSort.asc);if(a instanceof Date&&b instanceof Date)return a-b;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=smartSort(e.concat(g),"a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=smartSort([a[c], b[c]],"a"),a[c]==d[0]?-1:1;var f=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"a");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=smartSort([a.id,b.id],"a"),a.id==e[0]?1:-1;e=smartSort([a.tagName,b.tagName],"a");return a.tagName==e[0]?1:-1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);smartSort(e.concat(g), "a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&&b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=smartSort([a[d].id,b[f].id],"a"),a[d].id==c[0]?-1:1;c=smartSort([a[d].tagName,b[f].tagName],"a");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=smartSort([a[d],b[f]],"a"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1; if(b.hasOwnProperty(f)&&b[f]instanceof Element||!a.hasOwnProperty(d))return-1;if(!b.hasOwnProperty(d))return 1}c=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"a");return a[Object.keys(a)[0]]==c[0]?1:-1}g=[a,b].sort();return g[0]>g[1]};smartSort.desc=function(a,b){if(null==a||void 0==a)return 1;if(null==b||void 0==b)return-1;var c=typeof a,e=c+typeof b;if(/^numbernumber$/ig.test(e))return b-a;if(/^stringstring$/ig.test(e))return b>a;if(/(string|number){2}/ig.test(e))return/string/i.test(c)? 1:-1;if(/number/ig.test(e)&&/object/ig.test(e)||/string/ig.test(e)&&/object/ig.test(e))return/object/i.test(c)?1:-1;if(/^objectobject$/ig.test(e)){a instanceof Array&&a.sort(smartSort.desc);b instanceof Array&&b.sort(smartSort.desc);if(a instanceof Date&&b instanceof Date)return b-a;if(a instanceof Array&&b instanceof Array){var e=Object.keys(a),g=Object.keys(b),e=smartSort(e.concat(g),"a"),d;for(d in e)if(c=e[d],a[c]!=b[c])return d=smartSort([a[c],b[c]],"d"),a[c]==d[0]?-1:1;var f=smartSort([a[Object.keys(a)[0]], b[Object.keys(b)[0]]],"d");return a[Object.keys(a)[0]]==f[0]?-1:1}if(a instanceof Element&&b instanceof Element){if(a.tagName==b.tagName)return e=smartSort([a.id,b.id],"d"),a.id==e[0]?-1:1;e=smartSort([a.tagName,b.tagName],"d");return a.tagName==e[0]?-1:1}if(a instanceof Date||b instanceof Date)return a instanceof Date?1:-1;if(a instanceof Array||b instanceof Array)return a instanceof Array?-1:1;e=Object.keys(a);g=Object.keys(b);smartSort(e.concat(g),"a");for(c=0;20>c;c++){d=e[c];f=g[c];if(a.hasOwnProperty(d)&& b.hasOwnProperty(f)){if(a[d]instanceof Element&&b[f]instanceof Element){if(a[d].tagName==b[f].tagName)return c=smartSort([a[d].id,b[f].id],"d"),a[d].id==c[0]?-1:1;c=smartSort([a[d].tagName,b[f].tagName],"d");return a[d].tagName==c[0]?-1:1}if(a[d]instanceof Element||b[f]instanceof Element)return a[d]instanceof Element?1:-1;if(a[d]!=b[f])return c=smartSort([a[d],b[f]],"d"),a[d]==c[0]?-1:1}if(a.hasOwnProperty(d)&&a[d]instanceof Element)return 1;if(b.hasOwnProperty(f)&&b[f]instanceof Element)return-1; if(!a.hasOwnProperty(d))return 1;if(!b.hasOwnProperty(d))return-1}c=smartSort([a[Object.keys(a)[0]],b[Object.keys(b)[0]]],"d");return a[Object.keys(a)[0]]==c[0]?-1:1}g=[a,b].sort();return g[0]<g[1]}
/* end */

Utilizar:

z = smartSort(z, 'asc'); // Ascending
z = smartSort(z, 'desc'); // Descending

Método jsFiddle smartSort (Array, "asc | desc")


2

Prueba este código:

HTML:

<div id="demo"></div>

Código JavaScript:

<script>
    (function(){
        var points = [40, 100, 1, 5, 25, 10];
        document.getElementById("demo").innerHTML = points;
        points.sort(function(a, b){return a-b});
        document.getElementById("demo").innerHTML = points;
    })();
</script>

2

Pruebe este código de la siguiente manera

var a = [5, 17, 29, 48, 64, 21];
function sortA(arr) {
return arr.sort(function(a, b) {
return a - b;
})
;} 
alert(sortA(a));

no es verdad ?
user7125929

1
var numArray = [140000, 104, 99];
numArray = numArray.sort((a,b) => a-b);
alert(numArray)

44
Bienvenido a StackOverflow. Su respuesta es idéntica a la respuesta aceptada. ¿Puede agregar alguna explicación a su respuesta para decir por qué esto debería preferirse a la respuesta aceptada?
Simplemente Ged

1

Si bien no es obligatorio en JavaScript, si desea que devuelva estrictamente -1, 0 o 1 (similar a cómo funciona el operador de nave espacial en PHP), puede usarlo .sort() compareFunctionMath.sign()

Lo compareFunctionsiguiente devuelve estrictamente -1, 0 o 1:

numArray.sort((a, b) => Math.sign(a - b));

Nota: Math.sign() no es compatible con Internet Explorer.


0

Esta es la solución ya propuesta y aceptada como método en el prototipo de matriz:

Array.prototype.sortNumeric = function () {
    return this.sort((a, b) => a - b);
};
Array.prototype.sortNumericDesc = function () {
    return this.sort((a, b) => b - a);
};

0

Como método de clasificación convierte los elementos de la matriz en una cadena. Entonces, a continuación también funciona bien con números decimales con elementos de matriz.

let productPrices = [10.33, 2.55, 1.06, 5.77];
console.log(productPrices.sort((a,b)=>a-b));

Y te da el resultado esperado.


0

Anular el método de clasificación.

Array.prototype.sortInt = function(){
    this.sort(function(a,b){return a-b});
}


numbers = [12,8,21,5,1,34];
numbers.sortInt()
//output -> [1,5,8,12,21,34]

0

La función de clasificación predeterminada es ordenar en orden de diccionario:

var ar = [10000,3,200];
console.log(ar.sort());
//it will sort like :=> [10000, 200, 3]

El anterior no es el caso que queremos para los números. Entonces, si tiene números enteros y la función de clasificación predeterminada no funciona (porque se clasifica en el orden del diccionario), entonces debe implementar su propia función:

var ar = [10000,3,-09,200];
function customSortHelpForNumber(number1, number2){
     return number1-number2;
}
console.log(ar.sort(customSortHelpForNumber));
//it will sort like :=> [3, 200, 10000]

Espero que tengas una pregunta en mente sobre cómo funciona. Aquí, cuando proporcionamos un método en función de clasificación, pasa dos números cada vez y si el número regresa

  • -ve valor o 0, mantiene el primer número en su lugar
  • + ve valor intercambiar el lugar.

Siguiendo esto para todos los números, ordena la matriz de enteros.

Si está utilizando ES6, escriba una función de flecha:

console.log(ar.sort((num1,num2)=> num1-num2));
    //it will sort like :=> [3, 200, 10000]

-1

Aquí está mi función de matriz de clasificación en la biblioteca de utilidades:

sortArray: function(array) {
    array.sort(function(a, b) {
        return a > b;
    });
},

# Let's test a string array
var arr = ['bbc', 'chrome', 'aux', 'ext', 'dog'];
utils.sortArray(arr);
console.log(arr);
>>> ["aux", "bbc", "chrome", "dog", "ext", remove: function]

# Let's test a number array
var arr = [55, 22, 1425, 12, 78];
utils.sortArray(arr);
console.log(arr);
>>> [12, 22, 55, 78, 1425, remove: function]

3
Esto es simplemente incorrecto! La función de clasificación debe devolver números negativos, 0 o positivos, no verdaderos o falsos.
jperelli

Como @jperelli ha mencionado, la función de clasificación necesita un número, no un booleano, para ser devuelto (y dado que hay 3 estados posibles, igual, arriba y abajo, esto es necesario para tener una clasificación estable). Como se indica su respuesta, no funciona. a-bdebería usarse en su lugar. (Puedes ponerte elegante y hacer un Number(a>b)-0.5, sin embargo, todavía no es un tipo estable).
ecc521
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.