0

My Question

How do I sort an array of strings by by another array of strings in Javascript?

Background

I am looking for a way to sort an array of strings via another array. Specifically I have a problem where I cannot sort alphabetically or numerically. I know that Javascript supports custom sort functions as seen in this example:

let numberArray = [40, 1, 5, 200];
function compareNumbers(a, b) {
  return a - b;
}
numberArray.sort(compareNumbers);

I am not sure how a custom string comparison function would work for the problem I am looking at. I have given two example arrays in part 1 and part 2 below. If you need further clarification please ask.

PART 1

Example arrays: Note that educationSorted is desired result of sorting education by educationLevel.

let education = [
  "High School",
  "Middle School",
  "Undergrad",
  "Middle School",
  "Middle School",
  "Middle School",
  "Middle School",
  "Graduate",
  "Elementary",
  "Elementary",
  "Elementary",
  "Elementary"
];

let educationLevel = ["Elementary", "Middle School", "High School", "Undergrad", "Graduate"];

let educationSorted = [
  "Elementary",
  "Elementary",
  "Elementary",
  "Elementary",
  "Middle School",
  "Middle School",
  "Middle School",
  "Middle School",
  "Middle School",
  "High School",
  "Undergrad",
  "Graduate"
];

PART 2

Same general problem but the arrays of strings is replaced by an array of arrays.

let education = [
  ["Bob", "High School"],
  ["Alice", "Middle School"],
  ["Jane Doe", "Undergrad"],
  ["alex", "Middle School"],
  ["Mega Alice", "Middle School"],
  ["Jhon Doe", "Middle School"],
  ["Minor Bob", "Middle School"],
  ["Chicken", "Graduate"],
  ["Minor Chicken", "Elementary"],
  ["Clones", "Elementary"],
  ["Clones", "Elementary"],
  ["Clones", "Elementary"]
];

let educationLevel = ["Elementary", "Middle School", "High School", "Undergrad", "Graduate"];

let education = [
  ["Clones", "Elementary"],
  ["Clones", "Elementary"],
  ["Clones", "Elementary"],
  ["Minor Chicken", "Elementary"],
  ["Alice", "Middle School"],
  ["Mega Alice", "Middle School"],
  ["Jhon Doe", "Middle School"],
  ["Minor Bob", "Middle School"],
  ["alex", "Middle School"],
  ["Bob", "High School"],
  ["Jane Doe", "Undergrad"],
  ["Chicken", "Graduate"]
];
AzJ
  • 199
  • 1
  • 11
  • I know the question was closed, but I updated my answer to work specifically with the problem you are trying to solve. – nullromo May 17 '21 at 17:40

2 Answers2

1

You could try using a custom sort function like this:

const educationLevel = [
  "Elementary",
  "Middle School",
  "High School",
  "Undergrad",
  "Graduate",
];

const education = [
  ["Bob", "High School"],
  ["Alice", "Middle School"],
  ["Jane Doe", "Undergrad"],
  ["alex", "Middle School"],
  ["Mega Alice", "Middle School"],
  ["Jhon Doe", "Middle School"],
  ["Minor Bob", "Middle School"],
  ["Chicken", "Graduate"],
  ["Minor Chicken", "Elementary"],
  ["Clones", "Elementary"],
  ["Clones", "Elementary"],
  ["Clones", "Elementary"],
];

const compareEntries = (a, b) => {
  const aPriority = educationLevel.findIndex((element) => {
    return element === a[1];
  });
  const bPriority = educationLevel.findIndex((element) => {
    return element === b[1];
  });
  return aPriority - bPriority;
};

education.sort(compareEntries);

This method uses the index of the educationLevel array to determine the sort order.

nullromo
  • 2,165
  • 2
  • 18
  • 39
1

Use this:

let education = [
  ["Bob", "High School"],
  ["Alice", "Middle School"],
  ["Jane Doe", "Undergrad"],
  ["alex", "Middle School"],
  ["Mega Alice", "Middle School"],
  ["Jhon Doe", "Middle School"],
  ["Minor Bob", "Middle School"],
  ["Chicken", "Graduate"],
  ["Minor Chicken", "Elementary"],
  ["Clones", "Elementary"],
  ["Clones", "Elementary"],
  ["Clones", "Elementary"]
];

let educationLevel = ["Elementary", "Middle School", "High School", "Undergrad", "Graduate"];

function sortFunc(a, b) {
  return educationLevel.indexOf(a[1]) - educationLevel.indexOf(b[1]);
}

education.sort(sortFunc);
console.log(education);
Prosy Arceno
  • 2,616
  • 1
  • 8
  • 32