0

I've looked through several posts with similar with issues but I couldn't find one which solves my problem. The others all seemed to be sorting using another array of the same size or by value.

I have two arrays which look like this:

var allCategories = ['Campus', 'Building', 'Floor', 'Room', 'Lecture Theatre', 'Lab'];
var currentCategories = ['Room', 'Lab', 'Campus'];

How can I sort currentCategories so that the order matches that of allCategories?

Desired output:

currentCategories --> ['Campus', 'Room', 'Lab'];

3 Answers 3

5

"Sort this array by the indices of its elements in that array":

currentCategories.sort(function(a, b) {
  return allCategories.indexOf(a) - allCategories.indexOf(b);
});
// => ["Campus", "Room", "Lab"]
Sign up to request clarification or add additional context in comments.

Comments

3

If all that you want is the order of allCategories with the members of currentCategories, you can do the following.

allCategories.filter(function(x){return currentCategories.indexOf(x) != -1})

This assumes that you are treating each array as a set of non-repeating elements. As mentioned in the comments, this method may drop duplicate elements from the final value, or not order duplicate elements in the way you might intend.

6 Comments

Faster but fails on duplicates. (+1 anyway :D ) (EDIT: not a complaint; in OP's use case there probably aren't any duplicates. But caveat emptor and all that)
@Amadan Thanks for the +1. I am not sure I would say that it fails on duplicate values, but rather that sorting an array of values by the ordering defined in a second array produces undefined results if a given value occurs more than once in the ordering array. I mean, if x appears at index 1 and 5 in the ordering array, how do we order it in the primary array (currentCategories in this case). Is it after the values at indices < 5 or before the values at indices > 1?
What I meant is, if the array-to-be-sorted were to be ['Room', 'Lab', 'Campus', 'Room'], you would sort a four-element list into a three-element one.
@Amadan Thanks for the input. I didn't think you were complaining, I just didn't see the length edge case at first.
@Amadan you are correct. There are no duplicate values.
|
0

The Array.Sort method can be supplied a custom function. You could do something like this:

currentCategories.sort(function(a, b) {
    var i = allCategories.indexOf(a),
        j = allCategories.indexOf(b);           
    return i - j;
});

I haven't checked the behaviour for when there are values in currentCategories that are not in allCategories. But then, it wouldn't be living up to its name if that were the case.

If this is a common case, you could generalise it along the following lines:

function sortByList(list) {
    return function (a, b) { return list.indexOf(a) - list.indexOf(b); };
}

And call it thusly:

currentCategories.sort(sortByList(allCategories));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.