2013-06-03 46 views
12

cho giờ tôi đã cố gắng tìm ra cách sắp xếp 2 mảng phụ thuộc.javascript, sắp xếp 2 mảng phụ thuộc

Giả sử tôi có 2 mảng.

Đầu tiên một:

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

và thứ hai:

array2 = [3, 7, 1]; 

tôi sắp xếp đầu tiên với array1.sort(); và nó trở thành [aaaaaa, cccccc, zzzzzz] bây giờ những gì tôi muốn được rằng điều thứ hai trở thành [7, 1, 3]

Tôi nghĩ rằng nó khá đơn giản nhưng tôi đang cố gắng thực hiện điều này trong một cái gì đó phức tạp hơn một chút, im mới và tôi tiếp tục pha trộn mọi thứ.

Cảm ơn

+0

Điều này dường như với tôi giống như nó gần như là một vấn đề về cặp khóa/giá trị. Trong đó aaaaa là khóa cho 7, ccccc khóa cho 1 và zzzzz khóa cho 3. Trường hợp sử dụng của bạn hoàn toàn yêu cầu bạn duy trì hai mảng riêng biệt hoặc bạn sẽ mở để kết hợp chúng thành một mảng đối tượng tương tự như: arr = [{"key": "aaaaaa", "value": 7}, {"key": "zzzzzz", "value": 3}, ........]? –

Trả lời

1

Thay vì hai mảng của các kiểu dữ liệu (chuỗi, số), bạn có thể làm cho một mảng của các đối tượng mà một tài sản của đối tượng là chuỗi (có chứa "aaaaa", "cccccc", "zzzzzz") và một là số (7,1,3). Bằng cách này, bạn sẽ chỉ có một mảng, mà bạn can sort by any property và thuộc tính khác sẽ vẫn được đồng bộ hóa.

11

tôi sẽ "zip" chúng vào một mảng các đối tượng, sau đó sắp xếp rằng với một callback tùy chỉnh sắp xếp, sau đó "giải nén" chúng trở lại vào hai mảng bạn muốn:

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

Dưới đây là một working fiddle.

1

Assumption:

  • Các mảng là cùng độ dài (điều này được ngụ ý của câu hỏi của bạn)
  • các nội dung có thể được so sánh với >< (true trong ví dụ của bạn, nhưng tôi muốn làm cho nó rõ ràng rằng nó đã được giả định ở đây)

Vì vậy, chúng tôi có thể sử dụng sắp xếp chèn.

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 yêu cầu một giải pháp có thể không có vòng –

+1

@YuriyGalanter "nếu có thể tôi muốn một giải pháp chỉ với" fors "và nếu" "không, anh ta đã yêu cầu một vòng VỚI –

+0

@YuriyGalanter mặc dù bây giờ anh ta đã loại bỏ bất kỳ tham chiếu đến vòng nào cả –

1

Nó chỉ như vậy xảy ra tôi đã có một số mã cũ nằm xung quanh mà có thể làm các trick:

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

Xin lỗi, tôi không làm 'fors'. Ít nhất không phải khi tôi không phải làm vậy.

fiddle.


Ngoài ra, một sự thay thế fiddle rằng sắp xếp các kết quả khi đưa ra một mảng các đối tượng như thế này:

đưa ra:

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

kết quả đầu ra:

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

Sử dụng một giải pháp tìm thấy here để tìm chỉ mục mới sau khi sắp xếp một mảng, bạn có thể pply các chỉ số đó đến array2 như vậy.

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

Dưới đây là một chức năng đơn giản mà sẽ làm các trick:

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

Output:

Before..: ["zzzzz", "aaaaaa", "ccccc"] [3, 7, 1] 
After...: ["aaaaaa", "ccccc", "zzzzz"] [7, 1, 3] 
Các vấn đề liên quan