Sort Array by Another Array

12-07-2017
code-snippet

Problem: I have a large array of objects that I want to be able to easily sort based on the order of another array. For example: I have an array of objects that look like:

1
[...{ key: "a", value: "hi" }, { key: "b", value: "bye" }...]

And I want sort the array by another array based on a given parameter like key. I can do this by calling a simple function that return my large source array in sorted order.

The function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function sortArrayByArray(arrayToSort, arrayToSortBy, keyToSortBy) {
let reference_object = {};

// Build a reference object
for (let i = 0; i < arrayToSortBy.length; i++) {
reference_object[arrayToSortBy[i][keyToSortBy]] = i;
}

arrayToSort.sort(function(a, b) {
return reference_object[a[keyToSortBy]] - reference_object[b[keyToSortBy]];
});

return arrayToSort;
}

Let’s break this down. The sortArrayByArray() function receives 3 arguments, the arrayToSort which is our large source array, arrayToSortby which tells our sorting function how we want things ordered, and finally keyToSortBy which is the parameter that we want to use for sorting.

The first thing we do is create a simple object that will hold reference information later used by the sorting function, we call the object reference_object.

1
let reference_object = {};

Next, we need to populate the reference_object with information that will be helpful when we start sorting.

1
2
3
for (let i = 0; i < arrayToSortBy.length; i++) {
reference_object[arrayToSortBy[i][keyToSortBy]] = i;
}

Simply, what we’re doing is looping over the arrayToSortBy and assigning an integer, i, to the matching key value. For example, in our arrayToSortBy the first object is { key: "b" }, in our reference_object this would become { b: 0 } (remember, we start on the zero index). If our full arrraToSortBy looks like:

1
const arrayToSortBy = [{ key: "b" }, { key: "c" }, { key: "d" }, { key: "a" }];

Our new reference_object would look like:

1
2
3
4
5
6
{
a: 3,
b: 0,
c: 1,
d: 2
}

Finally, we use the sort() function to ‘sort’ each of the objects in the arrayToSort based on it’s matching “key’s” value. Sort takes in two values and determines which is greater using a comparison function and returns a -1, 0, 1 value. Because we first create the reference_object to define the order which we want to sort things we aren’t leaving it up to the sort() function to make that decision for us based on the string value of a certain parameter or something similar.

All together:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const arrayToSortBy = [{ key: "b" }, { key: "c" }, { key: "d" }, { key: "a" }];
const arrayToSort = [
{ key: "a", value: "hi" },
{ key: "a", value: "hi" },
{ key: "b", value: "hi" },
{ key: "b", value: "hi" },
{ key: "c", value: "hi" },
{ key: "b", value: "hi" },
...
]

function sortArrayByArray(arrayToSort, arrayToSortBy, keyToSortBy) {
let reference_object = {};

for (var i = 0; i < arrayToSortBy.length; i++) {
reference_object[arrayToSortBy[i][keyToSortBy]] = i;
}

arrayToSort.sort(function(a, b) {
return reference_object[a[keyToSortBy]] - reference_object[b[keyToSortBy]];
});

return arrayToSort;
}

console.log(sortArrayByArray(arraySource, arrayReference, "key"));