2013-06-03 11 views
12

od wielu godzin próbuję wymyślić sposób sortowania 2 tablic w zależności.javascript, sortuj 2 tablice w zależności

Załóżmy, że mam 2 tablice.

Pierwszy:

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

a drugi:

array2 = [3, 7, 1]; 

sortować pierwszy jeden z array1.sort(); i staje [aaaaaa, cccccc, zzzzzz] teraz to, co chcę jest, że drugi człowiek staje [7, 1, 3]

Myślę, że to całkiem proste, ale próbuję wprowadzić to w coś nieco bardziej skomplikowanego, Jestem nowy i ciągle miksuję rzeczy.

Dzięki

+0

Wydaje mi się, że to prawie problem z parą klucz/wartość. Gdzie aaaa jest kluczem dla 7, ccccc kluczem dla 1, a zzzzz kluczem dla 3. Czy twój przypadek użycia absolutnie wymaga zachowania dwóch odrębnych tablic lub byłbyś otwarty na łączenie ich w jedną tablicę obiektów podobnych do: arr = [{"key": "aaaaaa", "value": 7}, {"key": "zzzzzz", "value": 3}, ........]? –

Odpowiedz

1

Zamiast dwóch tablic prymitywnych typów (ciągi, cyfr) można zrobić tablicę obiektów, gdzie jedna właściwość obiektu jest ciąg (zawierający „aaaaa”, „CCCCCC”, „Zzzzzz”) a inny to liczba (7,1,3). W ten sposób będziesz mieć tylko jedną tablicę, którą ty i druga właściwość pozostaną zsynchronizowane.

11

bym „zip” je w jedną tablicę obiektów, a następnie posortować, że przy zwrotnego zwyczaj sortowania, a następnie „rozpakować” je z powrotem do dwóch tablicach chciałeś:

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); 

Oto working fiddle.

1

Założenie:

  • Macierze są tej samej długości (jest implikowane przez swoje pytanie)
  • zawartość może być porównywana z > i < (prawdziwe w swoim przykładzie, ale chciałem to zrobić jasne, że zostało tu założone)

Tak więc możemy użyć sortowania wstawiania.

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

OP poprosił o możliwe rozwiązanie bez pętli –

+1

@YuriyGalanter "jeśli jest to możliwe, chciałbym rozwiązanie z tylko" fors "i jeśli" "nie poprosił o jeden z pętlami –

+0

@YuriyGalanter choć teraz został usunięty wszelkie odniesienia do pętli w ogóle –

1

Tak się składa, że ​​miałem jakiś stary kod leżące wokół, że może załatwić sprawę:

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 
*/ 

Przykro mi, ale nie rób "Fors. Przynajmniej nie, kiedy nie muszę.

I fiddle.


również alternatywny fiddle sortuje rezultaty przy podawaniu szereg obiektów tak:

Dane:

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

Wyjścia:

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

stosując roztwór znaleźć here, aby znaleźć nowe indeksy po sortowaniu tablic, możesz przesyłaj te wskaźniki do array2, tak jak.

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

Oto prosta funkcja, która załatwi:

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); 

wyjściowa:

Before..: ["zzzzz", "aaaaaa", "ccccc"] [3, 7, 1] 
After...: ["aaaaaa", "ccccc", "zzzzz"] [7, 1, 3] 
Powiązane problemy