1

I have two arrays. I should do a normal sort on one (descending or ascending) and sort the other according to how the first array is sorted. This is because each element in the first array has a relationship with the same index element on the second array, and I must keep this relationship true. For example:

sortThis=[3,1,2];
sortAccording=["With 3","With 1","With 2];

I couldn't find any way to take the index changes from JavaScript's sort function.

2
  • 1
    do they have to be in separate arrays? Commented Dec 22, 2012 at 15:55
  • they are separate when i take them and i must output two separate arrays as well. but if merging and splitting them again solves the problem then its good. Commented Dec 22, 2012 at 15:59

3 Answers 3

3

Solution: To achieve that, you have to zip both arrays in just one. This is, given you have this two array:

sortThis=[3,1,2];
sortAccording=["With 3","With 1","With 2];

After zip them, you will have the following array:

zipped = [{a: 3, b: "With 3"}, {a: 1, b: "With 1"}, {a: 2, b: "With 2"}];

Then, you sort it by a in order to have:

zippedAndSorted = [{a: 1, b: "With 1"}, {a: 2, b: "With 2"}, {a: 3, b: "With 3"}];

What next?

Well, once you have this array sorted by what you want, you have to extract their values with the map function and finnaly you will have your two arrays sorted by the same criteria:

The code:

// your arrays
sortThis=[3,1,2];
sortAccording=["With 3","With 1","With 2"];

// the zip function    
function zip(a,b) {
    return a.map(function(aa, i){ return { i: aa, j: b[i]};} )
};               

// ziping and sorting the arrays
var zipped = zip(sortThis, sortAccording);
zippedAndSorted = zipped.sort(function(a,b){ return a.i - b.i; });

// your two sorted arrays
sortedThis = zippedAndSorted.map(function(a){ return a.i;});
sortedAccording = zippedAndSorted.map(function(a){ return a.j;});

You also can see it working here: http://jsfiddle.net/lontivero/cfpcJ/

Good luck!

Sign up to request clarification or add additional context in comments.

7 Comments

Using objects in zip is hardly a good idea. You'd be better off with array of arrays - this way both sorting and "unzipping" can be greatly simplified.
@thg435: What's the difference? An array is just an object with numerical properties, and it would not be used differently in the code here. Theoretically, you'd need a tuple.
@Bergi: the difference is that javascript knows how to sort a multidimensional array.
@thg435: Huh, what? No, it does not. You still would need the custom compare function, especially when sorting numbers like the OP.
@thg435: Then try [[2,0],[10,1]].sort() or [["a",0], ["b",1], ["a,a",2],["a,_",3]].sort()
|
1

For example:

function zip(a, b) {
    var i = 0, j = 0, r = [];
    while(i < a.length && j < b.length)
        r.push([a[i++], b[j++]]);
    return r;
}

function unzip(r) {
    var a = [], b = [];
    for(var i = 0; i < r.length; i++) {
        a.push(r[i][0]);
        b.push(r[i][1]);
    }
    return [a, b];
}

r = zip(sortAccording, sortThis);
r.sort();
r = unzip(r);

sortAccording = r[0]
sortThis = r[1]

Another way:

result = sortAccording.
    map(function(elem, pos) { return [elem, pos]}).
    sort().
    map(function(elem) { return sortThis[elem[1]]})

Better implementations of zip and unzip (both working with variable number of arguments):

zip = function() {
    var args = [].slice.call(arguments, 0);
    return args[0].map(function(_, i) {
        return args.map(function(a) {
            return a[i]
        })
    })
}

unzip = function(a) {
    return a[0].map(function(_, i) {
        return a.reduce(function(y, e) {
            return y.concat(e[i])
        }, [])
    })
}

2 Comments

In your zip function, isn't i always equal to j? If so, why not omit j?
@Andomar: good call! Here's a nicer implementation
0

I have a simple solution to this. Create a third array of indexes. Just sort that index array based on the sort of first array.

  var indexArray = [];
  for (var i=0; i < sortThis.length; i++) {
    indexArray[i] = i;
  }

  indexArray.sort(function(a, b) {
    return (sortThis[a] > sortThis[b]) ? 1 : (sortThis[a] === sortThis[b]) ? 0 : -1;
  });

  // Now you have the sorted index ready
  console.log("The first elements in the arrays are: " + sortThis(indexArray[0]) + " and " +  sortAccording(indexArray[0]));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.