﻿ Sort an Array of Objects Based on Another Array of Ids - ITCodar

# Sort an Array of Objects Based on Another Array of Ids

## Sort an array of objects based on another array of ids

Ramda really shines for these types of problems.

Where the size of the data is small, we can use a simple reduce function, and indexOf helper.

``// match id of object to required index and insertvar sortInsert = function (acc, cur) {  var toIdx = R.indexOf(cur.id, a);  acc[toIdx] = cur;  return acc;};// point-free sort function createdvar sort = R.reduce(sortInsert, []);// execute it now, or later as requiredsort(b);// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]``

This works well for small(ish) data sets but the indexOf operation on every iteration through the reduction is inefficient for large data sets.

We can remedy this by tackling the problem from the other side, lets use groupBy to group our objects by their id, thus creating a dictionary lookup (much better!). We can then simply map over the required indexes and transform them to their corresponding object at that position.

And here is the solution using this approach:

``var groupById = R.groupBy(R.prop('id'), b);var sort = R.map(function (id) {    return groupById[id];});sort(a);// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]``

Finally, this is yet another solution, which is very succinct:

``R.sortBy(R.pipe(R.prop('id'), R.indexOf(R.__, a)))(b);// [ { id: 2 }, { id: 3 }, { id: 1 }, { id: 4 } ]``

I love the way you can compose functions with behaviour and separate the algorithm from the data upon which it acts using Ramda. You end up with very readable, and easy to maintain code.

## Javascript - sort array based on another array

``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));``

## Sort Array of Objects based on position of value in another Array of Strings

You can loop the correct_order array and filter the unsorted array by using the js filter function. If filter match push to an new array.

``const UNSORTED = [{Type: 'Grass', Value: 'Wet'}, {Type: 'Sand', Value: 'Dry'}, {Type: 'Animal', Value: 'Dog'}];const CORRECT_ORDER = ['Animal','Plant','Sand','Grass'];let sorted = []CORRECT_ORDER.forEach(k => {  let n = UNSORTED.filter(obj => {    return obj.Type === k  })  if (n.length > 0) {    sorted.push(n);    }  })console.log(sorted);``

## Javascript sort array of objects based on another array

that ?

``const arr1 =       [ { id: 21, name: 'Joey',  vehicle: 'car' }       , { id: 6,  name: 'Kevin', vehicle: 'car' }       , { id: 10, name: 'Luis',  vehicle: 'van' }       ] const arr2 =       [ { id: 6,  name: 'Kevin' }       , { id: 21, name: 'Joey'  }       , { id: 10, name: 'Luis'  }       ]       // Arr1 ordered..const arr1_ord = arr2.map(a2=> arr1.find(x=>x.id===a2.id))console.log( arr1_ord )``
``.as-console-wrapper {max-height: 100%!important;top:0}``

## How to sort an array of objects using another array for reference?

You could use `Array.prototype.sort()` method to get the result.

``const data = [  { id: 2, name: 'carlos' },  { id: 1, name: 'maria' },  { id: 4, name: 'juan' },  { id: 3, name: 'pepe' },];const order = [1, 2, 3, 4, 5];data.sort((x, y) => order.indexOf(x.id) - order.indexOf(y.id));console.log(data);``

## JavaScript - sorting an array of IDs based on another array of IDS that is a subset of it

Below is a simple example, I've used IndexOf to get the index and sort on this for the first part,. Only slight gotcha is that -1 would be at the wrong side of the sort, so a check for this and I just return a large number to place at the end instead.

The second stage of the sort is then performed on an equality check, and it's just a simple (b-a) compare, for a descending sort.

``const arr = [   { id: "5ffca1c771138d181c3bde0b", otherValue: 10 },    { id: "5ffca1c771138d181c3bde0e", otherValue: 3},    { id: "5ffca1c771138d181c3bde12", otherValue: 7},   { id: "5ffca1c771138d181c3bde04", otherValue: 1},    { id: "5ffca1c771138d181c3bde08", otherValue: 11}];const arrIds = [ "5ffca1c771138d181c3bde12", "5ffca1c771138d181c3bde08"];function s1(a) {  let i = arrIds.indexOf(a.id);  if (i < 0) i = Number.MAX_SAFE_INTEGER;  return i;}arr.sort((a,b) => {  let s = s1(a) - s1(b);  if (s === 0) return b.otherValue - a.otherValue;  return s;});console.log(arr);``

## Re-ordering one array of objects based on data from another array in Javascript (React)

A Map will do the job just fine:

``const upcomingSessions = [  {therapistId: 5},  {therapistId: 8},  {therapistId: 9},  {therapistId: 7}];const consultants = [  {id: 1},  {id: 2},  {id: 3},  {id: 5},  {id: 6},  {id: 7},  {id: 8},  {id: 9},  {id: 10},  {id: 11},  {id: 12}];const recentConsultants = new Map(upcomingSessions.map(us => [us.therapistId, ]));consultants.forEach(c => recentConsultants.set(c.id, c));console.log([...recentConsultants.values()]);``