Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript - sort array based on another array

Tags:

javascript

People also ask

How do you sort an array in ascending order based on the ranks of each element which is in the another array?

The short answer is: std::sort . The basic idea is to create a std::vector<std::pair<int,int>> and then simply sort that via std::sort . The rest of the code is about copying the values and ranks into that vector and copying the values out of it after sorting.

How do you assign a sorted array to another array in Java?

You can sort within the array using Arrays. sort() method, or if you want to sort in a different array, you can take following steps: Copy the array to new array. Sort the new array and then sort.

How do you sort an array in a specific order?

Sorting an array of objects in javascript is simple enough using the default sort() function for all arrays: const arr = [ { name: "Nina" }, { name: "Andre" }, { name: "Graham" } ]; const sortedArr = arr. sort((a,b) => { if ( a.name < b.name ){ return -1; } if ( a.name > b.name ){ return 1; } return 0; });


One-Line answer.

itemsArray.sort(function(a, b){  
  return sortingArr.indexOf(a) - sortingArr.indexOf(b);
});

Or even shorter:

itemsArray.sort((a, b) => sortingArr.indexOf(a) - sortingArr.indexOf(b));

Something like:

items = [ 
    ['Anne', 'a'],
    ['Bob', 'b'],
    ['Henry', 'b'],
    ['Andrew', 'd'],
    ['Jason', 'c'],
    ['Thomas', 'b']
]

sorting = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
result = []

sorting.forEach(function(key) {
    var found = false;
    items = items.filter(function(item) {
        if(!found && item[1] == key) {
            result.push(item);
            found = true;
            return false;
        } else 
            return true;
    })
})

result.forEach(function(item) {
    document.writeln(item[0]) /// Bob Jason Henry Thomas Andrew
})

Here's a shorter code, but it destroys the sorting array:

result = items.map(function(item) {
    var n = sorting.indexOf(item[1]);
    sorting[n] = '';
    return [n, item]
}).sort().map(function(j) { return j[1] })

If you use the native array sort function, you can pass in a custom comparator to be used when sorting the array. The comparator should return a negative number if the first value is less than the second, zero if they're equal, and a positive number if the first value is greater.

So if I understand the example you're giving correctly, you could do something like:

function sortFunc(a, b) {
  var sortingArr = [ 'b', 'c', 'b', 'b', 'c', 'd' ];
  return sortingArr.indexOf(a[1]) - sortingArr.indexOf(b[1]);
}

itemsArray.sort(sortFunc);

Case 1: Original Question (No Libraries)

Plenty of other answers that work. :)

Case 2: Original Question (Lodash.js or Underscore.js)

var groups = _.groupBy(itemArray, 1);
var result = _.map(sortArray, function (i) { return groups[i].shift(); });

Case 3: Sort Array1 as if it were Array2

I'm guessing that most people came here looking for an equivalent to PHP's array_multisort (I did) so I thought I'd post that answer as well. There are a couple options:

1. There's an existing JS implementation of array_multisort(). Thanks to @Adnan for pointing it out in the comments. It is pretty large, though.

2. Write your own. (JSFiddle demo)

function refSort (targetData, refData) {
  // Create an array of indices [0, 1, 2, ...N].
  var indices = Object.keys(refData);

  // Sort array of indices according to the reference data.
  indices.sort(function(indexA, indexB) {
    if (refData[indexA] < refData[indexB]) {
      return -1;
    } else if (refData[indexA] > refData[indexB]) {
      return 1;
    }
    return 0;
  });

  // Map array of indices to corresponding values of the target array.
  return indices.map(function(index) {
    return targetData[index];
  });
}

3. Lodash.js or Underscore.js (both popular, smaller libraries that focus on performance) offer helper functions that allow you to do this:

    var result = _.chain(sortArray)
      .pairs()
      .sortBy(1)
      .map(function (i) { return itemArray[i[0]]; })
      .value();

...Which will (1) group the sortArray into [index, value] pairs, (2) sort them by the value (you can also provide a callback here), (3) replace each of the pairs with the item from the itemArray at the index the pair originated from.


this is probably too late but, you could also use some modified version of the code below in ES6 style. This code is for arrays like:

var arrayToBeSorted = [1,2,3,4,5];
var arrayWithReferenceOrder = [3,5,8,9];

The actual operation :

arrayToBeSorted = arrayWithReferenceOrder.filter(v => arrayToBeSorted.includes(v));

The actual operation in ES5 :

arrayToBeSorted = arrayWithReferenceOrder.filter(function(v) {
    return arrayToBeSorted.includes(v);
});

Should result in arrayToBeSorted = [3,5]

Does not destroy the reference array.


Why not something like

//array1: array of elements to be sorted
//array2: array with the indexes

array1 = array2.map((object, i) => array1[object]);

The map function may not be available on all versions of Javascript


function sortFunc(a, b) {
  var sortingArr = ["A", "B", "C"];
  return sortingArr.indexOf(a.type) - sortingArr.indexOf(b.type);
}

const itemsArray = [
  {
    type: "A",
  },
  {
    type: "C",
  },
  {
    type: "B",
  },
];
console.log(itemsArray);
itemsArray.sort(sortFunc);
console.log(itemsArray);