Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript, sort 2 array dependently

for hours i've been trying to figure out how to sort 2 array dependently.

Let's say I have 2 arrays.

First one:

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

and the second one:

array2 = [3, 7, 1];

I sort the first one with array1.sort(); and it becomes [aaaaaa, cccccc, zzzzzz] now what I want is that the second one becomes [7, 1, 3]

I think it's quite simple but i'm trying to implement this in something a little more complex, im new and i keep mixing up things.

Thanks

like image 349
Bob J Avatar asked Jun 03 '13 00:06

Bob J


4 Answers

I would "zip" them into one array of objects, then sort that with a custom sort callback, then "unzip" them back into the two arrays you wanted:

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

Here's a working fiddle.

like image 169
Ezekiel Victor Avatar answered Oct 12 '22 02:10

Ezekiel Victor


Here's a simple function that will do the 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] 
like image 45
acdcjunior Avatar answered Oct 12 '22 03:10

acdcjunior


Instead of two arrays of primitive types (strings, numbers) you can make an array of objects where one property of the object is string (containing "aaaaa", "cccccc", "zzzzzz") and another is number (7,1,3). This way you will have one array only, which you can sort by any property and the other property will remain in sync.

like image 1
Yuriy Galanter Avatar answered Oct 12 '22 02:10

Yuriy Galanter


It just so happens I had some old code lying around that might do the 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
*/

Sorry, I don't do 'fors'. At least not when I don't have to.

And fiddle.


Also, an alternative fiddle that sorts the results when given an array of objects like this:

given:

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

outputs:

[
  {str: "aaaaa", value: 7},
  {str: "ccccc", value: 1},
  {str: "zzzzz", value: 3}
]
like image 1
jongo45 Avatar answered Oct 12 '22 02:10

jongo45