Sort two arrays the same way

You can sort the existing arrays, or reorganize the data.

Method 1: To use the existing arrays, you can combine, sort, and separate them: (Assuming equal length arrays)

var names = ["Bob","Tom","Larry"];
var ages =  ["10", "20", "30"];

//1) combine the arrays:
var list = [];
for (var j = 0; j < names.length; j++) 
    list.push({'name': names[j], 'age': ages[j]});

//2) sort:
list.sort(function(a, b) {
    return ((a.name < b.name) ? -1 : ((a.name == b.name) ? 0 : 1));
    //Sort could be modified to, for example, sort on the age 
    // if the name is the same.
});

//3) separate them back out:
for (var k = 0; k < list.length; k++) {
    names[k] = list[k].name;
    ages[k] = list[k].age;
}

This has the advantage of not relying on string parsing techniques, and could be used on any number of arrays that need to be sorted together.

Method 2: Or you can reorganize the data a bit, and just sort a collection of objects:

var list = [
    {name: "Bob", age: 10}, 
    {name: "Tom", age: 20},
    {name: "Larry", age: 30}
    ];

list.sort(function(a, b) {
    return ((a.name < b.name) ? -1 : ((a.name == b.name) ? 0 : 1));
});

for (var i = 0; i<list.length; i++) {
    alert(list[i].name + ", " + list[i].age);
}
​

For the comparisons,-1 means lower index, 0 means equal, and 1 means higher index. And it is worth noting that sort() actually changes the underlying array.

Also worth noting, method 2 is more efficient as you do not have to loop through the entire list twice in addition to the sort.

http://jsfiddle.net/ghBn7/38/


This solution (my work) sorts multiple arrays, without transforming the data to an intermediary structure, and works on large arrays efficiently. It allows passing arrays as a list, or object, and supports a custom compareFunction.

Usage:

let people = ["john", "benny", "sally", "george"];
let peopleIds = [10, 20, 30, 40];

sortArrays([people, peopleIds]);
[["benny", "george", "john", "sally"], [20, 40, 10, 30]] // output

sortArrays({people, peopleIds});
{"people": ["benny", "george", "john", "sally"], "peopleIds": [20, 40, 10, 30]} // output

Algorithm:

  • Create a list of indexes of the main array (sortableArray)
  • Sort the indexes with a custom compareFunction that compares the values, looked up with the index
  • For each input array, map each index, in order, to its value

Implementation:

/**
 *  Sorts all arrays together with the first. Pass either a list of arrays, or a map. Any key is accepted.
 *     Array|Object arrays               [sortableArray, ...otherArrays]; {sortableArray: [], secondaryArray: [], ...}
 *     Function comparator(?,?) -> int   optional compareFunction, compatible with Array.sort(compareFunction)
 */
function sortArrays(arrays, comparator = (a, b) => (a < b) ? -1 : (a > b) ? 1 : 0) {
    let arrayKeys = Object.keys(arrays);
    let sortableArray = Object.values(arrays)[0];
    let indexes = Object.keys(sortableArray);
    let sortedIndexes = indexes.sort((a, b) => comparator(sortableArray[a], sortableArray[b]));

    let sortByIndexes = (array, sortedIndexes) => sortedIndexes.map(sortedIndex => array[sortedIndex]);

    if (Array.isArray(arrays)) {
        return arrayKeys.map(arrayIndex => sortByIndexes(arrays[arrayIndex], sortedIndexes));
    } else {
        let sortedArrays = {};
        arrayKeys.forEach((arrayKey) => {
            sortedArrays[arrayKey] = sortByIndexes(arrays[arrayKey], sortedIndexes);
        });
        return sortedArrays;
    }
}

See also https://gist.github.com/boukeversteegh/3219ffb912ac6ef7282b1f5ce7a379ad


You could get the indices of name array using Array.from(name.keys()) or [...name.keys()]. Sort the indices based on their value. Then use map to get the value for the corresponding indices in any number of related arrays

const indices = Array.from(name.keys())
indices.sort( (a,b) => name[a].localeCompare(name[b]) )

const sortedName = indices.map(i => name[i]),
const sortedAge = indices.map(i => age[i])

Here's a snippet:

const name = ["Bob","Tom","Larry"],
      age =  ["10", "20", "30"],
      
      indices = Array.from(name.keys())
                     .sort( (a,b) => name[a].localeCompare(name[b]) ),
                     
      sortedName = indices.map(i => name[i]),
      sortedAge = indices.map(i => age[i])

console.log(indices)
console.log(sortedName)
console.log(sortedAge)

Tags:

Javascript