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?

peirix
fuente
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.

aks
fuente
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
MarzSocks
fuente
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.

Paul Dixon
fuente
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 .

jjjjs
fuente
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)

dy_
fuente
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í .

Negro
fuente
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;
usuario3587638
fuente
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 :)

Chait
fuente
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);
Peter Mortensen
fuente
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

Merbin Joe
fuente
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

Suicidio comercial
fuente
¿ 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;
   }
}
leet101
fuente
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]
Ali Khosro
fuente
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}]**
Umesh
fuente
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")

SpYk3HH
fuente
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>
Sunny SM
fuente
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));
usuario7125929
fuente
no es verdad ?
user7125929
1
var numArray = [140000, 104, 99];
numArray = numArray.sort((a,b) => a-b);
alert(numArray)
Vardaman PK
fuente
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.

Grant Miller
fuente
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);
};
Error 404
fuente
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.

Anshul Chaurasia
fuente
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]
sandes
fuente
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]
JustIn
fuente
-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]
fuego de fuego
fuente
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