2012-07-16 19 views
23

Por ejemplo, si tengo estas matrices:Ordenar dos matrices de la misma manera

var name = ["Bob","Tom","Larry"]; 
var age = ["10", "20", "30"]; 

Y uso name.sort() el orden de la matriz "nombre" se convierte en:

var name = ["Bob","Larry","Tom"]; 

Pero, ¿cómo puede Ordeno la matriz de "nombre" y hago que la matriz de "edad" mantenga el mismo orden? De esta manera:

var name = ["Bob","Larry","Tom"]; 
var age = ["10", "30", "20"]; 
+0

¿Existe la posibilidad de cambiar la forma en que almacena los datos? Para matrices anidadas, u objetos – zerkms

+0

Voy a adivinar y decir que no hay forma de hacerlo con el código que ha publicado actualmente. Cada matriz no almacena suficiente información dentro de ella. El conjunto de nombres en cualquier punto dado no sabe si se ha cambiado, no hay ninguna propiedad que tenga un orden de clasificación o similar. –

+0

posible duplicado de [JavaScript: manipular dos matrices] (http://stackoverflow.com/questions/8862220/javascript-manipulate-two-arrays) –

Respuesta

37

Puede ordenar las matrices existentes o reorganizar los datos.

Método 1: Para utilizar las matrices existentes, se pueden combinar, clasificar y separar: (suponiendo que las matrices de igual longitud)

var names = ["Bob","Tom","Larry"]; 
var ages = ["10", "20", "30"]; 

//1) combine the arrays: 
var list = []; 
for (var j = 0; j < names.length; j++) 
    list.push({'name': names[j], 'age': ages[j]}); 

//2) sort: 
list.sort(function(a, b) { 
    return ((a.name < b.name) ? -1 : ((a.name == b.name) ? 0 : 1)); 
    //Sort could be modified to, for example, sort on the age 
    // if the name is the same. 
}); 

//3) separate them back out: 
for (var k = 0; k < list.length; k++) { 
    names[k] = list[k].name; 
    ages[k] = list[k].age; 
} 

Esto tiene la ventaja de no depender de técnicas de análisis de cadenas, y podrían usarse en cualquier cantidad de matrices que necesiten ordenarse juntas.

Método 2: O puede reorganizar los datos un poco, y simplemente ordenar una colección de objetos:

var list = [ 
    {name: "Bob", age: 10}, 
    {name: "Tom", age: 20}, 
    {name: "Larry", age: 30} 
    ]; 

list.sort(function(a, b) { 
    return ((a.name < b.name) ? -1 : ((a.name == b.name) ? 0 : 1)); 
}); 

for (var i = 0; i<list.length; i++) { 
    alert(list[i].name + ", " + list[i].age); 
} 
​ 

Para las comparaciones, -1 significa menor índice, 0 significa iguales, y 1 significa índice más alto. Y vale la pena señalar que sort() realmente cambia la matriz subyacente.

http://jsfiddle.net/ghBn7/38/

+0

muchas gracias !!!!!!!! – supercoolville

+0

Siempre olvido cómo hacer esto en javascript. Los lenguajes de script Serverside solo tienen esto incorporado ... demasiado estropeado, supongo. – AlexMA

+0

Esta es una muy buena respuesta con esas actualizaciones especialmente ... – Andrew

1

Usted está tratando de resolver 2 arrays independet sólo llamar a sort() en uno de ellos.

Una forma de lograr esto sería escribir su propio método de clasificación que se encargaría de esto, es decir, cuando intercambie 2 elementos in situ en la matriz "original", debería intercambiar 2 elementos en el lugar " atributo "array".

Aquí hay un pseudocódigo sobre cómo puede probarlo.

function mySort(originals, attributes) { 
    // Start of your sorting code here 
     swap(originals, i, j); 
     swap(attributes, i, j); 
    // Rest of your sorting code here 
} 
+1

En realidad estaba pensando lo mismo, sin embargo, parece bastante poco práctico cuando hay formas mucho más sencillas de hacerlo si los datos se almacenan de manera diferente. –

0

Se podría añadir el índice original de cada miembro en el valor, ordenar la matriz, a continuación, eliminar el índice y utilizarlo para volver a pedir la otra matriz. Solo funcionará cuando los contenidos sean cadenas o se puedan convertir ay desde cadenas exitosamente.

Otra solución es mantener una copia de la matriz original, luego de ordenarla, buscar dónde está cada miembro y ajustar la otra matriz de forma adecuada.

1

inspirado en @jwatts1980's answer, y @Alexander's answer here combiné ambas respuestas en una solución rápida y sucia; La matriz principal es la de ser resuelto, el resto se limita a seguir sus índices

NOTA: No es muy eficiente para muy matrices muy grandes

/* @sort argument is the array that has the values to sort 
    @followers argument is an array of arrays which are all same length of 'sort' 
    all will be sorted accordingly 
    example: 

    sortMutipleArrays(
     [0, 6, 7, 8, 3, 4, 9], 
     [ ["zr", "sx", "sv", "et", "th", "fr", "nn"], 
      ["zero", "six", "seven", "eight", "three", "four", "nine"] 
     ] 
    ); 

    // Will return 

    { 
    sorted: [0, 3, 4, 6, 7, 8, 9], 
    followed: [ 
     ["zr", th, "fr", "sx", "sv", "et", "nn"], 
     ["zero", "three", "four", "six", "seven", "eight", "nine"] 
    ] 
    } 
*/ 

Es posible que desee cambiar el método de firma/retorno estructura, pero eso debería ser fácil sin embargo.Lo hice de esta manera porque lo necesitaba

var sortMultipleArrays = function (sort, followers) { 
    var index = this.getSortedIndex(sort) 
    , followed = []; 
    followers.unshift(sort); 
    followers.forEach(function(arr){ 
    var _arr = []; 
    for(var i = 0; i < arr.length; i++) 
     _arr[i] = arr[index[i]]; 
    followed.push(_arr); 
    }); 
    var result = {sorted: followed[0]}; 
    followed.shift(); 
    result.followed = followed; 
    return result; 
}; 

var getSortedIndex = function (arr) { 
    var index = []; 
    for (var i = 0; i < arr.length; i++) { 
    index.push(i); 
    } 
    index = index.sort((function(arr){ 
    /* this will sort ints in descending order, change it based on your needs */ 
    return function (a, b) {return ((arr[a] > arr[b]) ? -1 : ((arr[a] < arr[b]) ? 1 : 0)); 
    }; 
    })(arr)); 
    return index; 
}; 
0

más simple explantion es la mejor, combinar las matrices, y luego extraer después de su clasificación: crear una matriz

name_age=["[email protected]","[email protected]","[email protected]"]; 

ordenar la matriz como antes, a continuación, extraiga el nombre y la edad, puede usar @ para reconocer dónde termina el nombre y comienza la edad. Tal vez no sea un método para los puristas, pero tengo el mismo problema y este es mi enfoque.

1

Es muy similar a jwatts1980's answer (Update 2). Considere leer Sorting with map.

name.map(function (v, i) { 
    return { 
     value1 : v, 
     value2 : age[i] 
    }; 
}).sort(function (a, b) { 
    return ((a.value1 < b.value1) ? -1 : ((a.value1 == b.value1) ? 0 : 1)); 
}).forEach(function (v, i) { 
    name[i] = v.value1; 
    age[i] = v.value2; 
}); 
2

Estaba teniendo el mismo problema y se me ocurrió esta solución increíblemente simple. En primer lugar combinar los Ellements asociados en cadenas en una matriz separada luego usar parseInt en su función de comparación de esta manera:

<html> 
<body> 
<div id="outPut"></div> 
<script> 
var theNums = [13,12,14]; 
var theStrs = ["a","b","c"]; 
var theCombine = []; 

for (var x in theNums) 
{ 
    theCombine[x] = theNums[x] + "," + theStrs; 
} 

var theSorted = theAr.sort(function(a,b) 
{ 
    var c = parseInt(a,10); 
    var d = parseInt(b,10); 
    return c-d; 
}); 
document.getElementById("outPut").innerHTML = theS; 
</script> 
</body> 
</html> 
Cuestiones relacionadas