Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort two arrays the same way

Tags:

javascript

For example, if I have these arrays:

var name = ["Bob","Tom","Larry"]; var age =  ["10", "20", "30"]; 

And I use name.sort() the order of the "name" array becomes:

var name = ["Bob","Larry","Tom"]; 

But, how can I sort the "name" array and have the "age" array keep the same order? Like this:

var name = ["Bob","Larry","Tom"]; var age =  ["10", "30", "20"]; 
like image 325
supercoolville Avatar asked Jul 16 '12 06:07

supercoolville


People also ask

How do I sort two arrays in PHP?

The array_multisort() function returns a sorted array. You can assign one or more arrays. The function sorts the first array, and the other arrays follow, then, if two or more values are the same, it sorts the next array, and so on.

How do you sort an array of arrays?

To sort an array of arrays in JavaScript, we can use the array sort method. We call array. sort with a callback that destructures the first entry from each nested array. Then we return the value to determine how it's sorted.


2 Answers

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/

like image 70
jwatts1980 Avatar answered Sep 19 '22 19:09

jwatts1980


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

like image 24
Bouke Versteegh Avatar answered Sep 21 '22 19:09

Bouke Versteegh