2013-06-03 9 views
12

per ore ho cercato di capire come ordinare 2 array in modo dipendente.javascript, array di ordinamento 2 in modo dipendente

Diciamo che ho 2 array.

Primo uno:

array1 = ['zzzzz', 'aaaaaa', 'ccccc']; 

e la seconda:

array2 = [3, 7, 1]; 

I sorta la prima con array1.sort(); e diventa [aaaaaa, cccccc, zzzzzz] ora quello che voglio è che la seconda si diventa [7, 1, 3]

Penso che sia abbastanza semplice, ma sto cercando di implementarlo in qualcosa di un po 'più complesso, Sono nuovo e continuo a mescolare le cose.

Grazie

+0

Questo mi sembra come se fosse quasi un problema di coppia chiave/valore. Dove aaaaa è la chiave per 7, ccccc la chiave per 1 e zzzzz la chiave per 3. Il tuo caso d'uso richiede assolutamente che tu mantenga due array distinti o sarai aperto a combinarli in una singola matrice di oggetti simile a: arr = [{"key": "aaaaaa", "valore": 7}, {"chiave": "zzzzzz", "valore": 3}, ........]? –

risposta

1

Invece di due array di tipi primitivi (stringhe, numeri) è possibile effettuare un array di oggetti in cui una proprietà dell'oggetto è stringa (contenente "AAAAA", "cccccc", "zzzzzz") e un altro è il numero (7,1,3). In questo modo si avrà solo un array, che si can sort by any property e l'altra proprietà rimarranno sincronizzati.

11

avrei "zip" li in un array di oggetti, quindi ordinare che con un callback di ordinamento, quindi "decomprimere" nuovamente dentro i due array che volevi:

var array1 = ['zzzzz', 'aaaaaa', 'ccccc'], 
    array2 = [3, 7, 1], 
    zipped = [], 
    i; 

for(i=0; i<array1.length; ++i) { 
    zipped.push({ 
     array1elem: array1[i], 
     array2elem: array2[i] 
    }); 
} 

zipped.sort(function(left, right) { 
    var leftArray1elem = left.array1elem, 
     rightArray1elem = right.array1elem; 

    return leftArray1elem === rightArray1elem ? 0 : (leftArray1elem < rightArray1elem ? -1 : 1); 
}); 

array1 = []; 
array2 = []; 
for(i=0; i<zipped.length; ++i) { 
    array1.push(zipped[i].array1elem); 
    array2.push(zipped[i].array2elem); 
} 

alert('Sorted arrays:\n\narray1: ' + array1 + '\n\narray2: ' + array2); 

Ecco un working fiddle.

1

Assunzione:

  • Gli array sono la stessa lunghezza (questo è implicito da eventuali domande)
  • i contenuti possono essere confrontati con > e < (vero nel tuo esempio, ma ho voluto farlo chiaro che è stato assunto qui)

Quindi possiamo usare un tipo di inserimento.

var value,len = array1.length; 
for (i=0; i < len; i++) { 
     value = array1[i]; 
     for (j=i-1; j > -1 && array1[j] > value; j--) { 
      array1[j+1] = array1[j]; 
      array2[j+1] = array2[j]; 
     } 

     items[j+1] = value; 
} 
+0

L'OP ha chiesto una possibile soluzione senza loop –

+1

@YuriyGalanter "se è possibile vorrei una soluzione con solo" fors "e if" "no ha chiesto uno con WITH loop –

+0

@YuriyGalanter sebbene ora abbia rimosso qualsiasi riferimento ai loop a tutti –

1

Si dà il caso che ho avuto un po 'di vecchio codice in giro che potrebbe fare il trucco:

function arrVirtualSortGetIndices(array,fnCompare){ 
    var index=array.map(function(e,i,a){return i;}); 
    fnCompare=fnCompare || defaultStringCompare; 
    var idxCompare=function (aa,bb){return fnCompare(array[aa],array[bb]);}; 
    index.sort(idxCompare); 
    return index; 

    function defaultStringCompare(aa,bb){ 
     if(aa<bb)return -1; 
     if(bb<aa)return 1; 
     return 0; 
    } 
    function defaultNumericalCompare(aa,bb){ 
     return aa-bb; 
    } 
} 

function arrReorderByIndices(array,indices){ 
    return array.map(
     function(el,ix,ar){ 
      return ar[indices[ix]]; 
     } 
    ); 
} 

var array1 = ['zzzzz', 'aaaaaa', 'ccccc']; 
var array2 = [3, 7, 1]; 
var indices=arrVirtualSortGetIndices(array1); 
var array2sorted=arrReorderByIndices(array2,indices); 
array2sorted; 

/* 
7,1,3 
*/ 

Siamo spiacenti, non faccio 'fors'. Almeno non quando non devo.

E fiddle.


Inoltre, un'alternativa fiddle che ordina i risultati quando dato un array di oggetti simili:

proposta:

var list = [ 
    {str:'zzzzz',value:3}, 
    {str:'aaaaa',value:7}, 
    {str:'ccccc',value:1} 
]; 

uscite:

[ 
    {str: "aaaaa", value: 7}, 
    {str: "ccccc", value: 1}, 
    {str: "zzzzz", value: 3} 
] 
0

Utilizzando una soluzione trovato here per trovare i nuovi indici dopo aver ordinato un array, è possibile piacciono quegli indici a array2 così.

function sortWithIndices(toSort) { 
    for (var i = 0; i < toSort.length; i++) { 
    toSort[i] = [toSort[i], i]; 
    } 
    toSort.sort(function(left, right) { 
    return left[0] < right[0] ? -1 : 1; 
    }); 
    toSort.sortIndices = []; 
    for (var j = 0; j < toSort.length; j++) { 
    toSort.sortIndices.push(toSort[j][2]); 
    toSort[j] = toSort[j][0]; 
    } 
    return toSort; 
} 


var array1 = ['zzzz', 'aaaa', 'cccc']; 
var array2 = [3, 7, 1]; 

// calculate the indices of array1 after sorting. (attached to array1.sortIndices) 
sortWithIndices(array1); 

// the final array after applying the sorted indices from array1 to array2 
var final = []; 

// apply sorted indices to array2 
for(var i = 0; i < array1.sortIndices.length; i++) 
    final[i] = array2[array1.sortIndices[i]]; 

// output results 
alert(final.join(",")); 

JSFiddle Demo

2

Ecco una semplice funzione che farà il trucco:

function sortTogether(array1, array2) { 
    var merged = []; 
    for(var i=0; i<array1.length; i++) { merged.push({'a1': array1[i], 'a2': array2[i]}); } 
    merged.sort(function(o1, o2) { return ((o1.a1 < o2.a1) ? -1 : ((o1.a1 == o2.a1) ? 0 : 1)); }); 
    for(var i=0; i<merged.length; i++) { array1[i] = merged[i].a1; array2[i] = merged[i].a2; } 
} 

Usage demo (fiddle here):

var array1 = ['zzzzz', 'aaaaaa', 'ccccc']; 
var array2 = [3, 7, 1]; 
console.log('Before..: ',array1,array2); 

sortTogether(array1, array2); // simply call the function 

console.log('After...: ',array1,array2); 

uscita:

Before..: ["zzzzz", "aaaaaa", "ccccc"] [3, 7, 1] 
After...: ["aaaaaa", "ccccc", "zzzzz"] [7, 1, 3] 
Problemi correlati