Sorting an array according to another sorted array index

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

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

      

I could not find a way to change the index using a JavaScript function sort

.

+1


source to share


3 answers


Solution: To achieve this, you must anchor both arrays with just one. This means that you have these two arrays:

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

      

After zip, they 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 to have:

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

      



What's next?

Well, if you have this array sorted by what you want, you have to extract their values ​​using the map function , and finally you will have your two arrays sorted by the same criteria:

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 can also see how it works here: http://jsfiddle.net/lontivero/cfpcJ/

Good luck!

+3


source


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]]})

      

More efficient implementations of zip and unzip (both operate on a 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])
        }, [])
    })
}

      

+1


source


I have a simple solution. Create a third array of indices. Just sort this indexed array based on the 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]));

      

0


source







All Articles