Array.sort() не для слабонервных. Особенно, когда речь идет о сортировке сложных структур данных.

Большинство руководств по JavaScript дают только краткое введение в Array.sort(). Обычно это:

let myArray = [3, 5, 7, 1, 0];
console.log(myArray.sort());

Ого, спасибо, Капитан Очевидность! Но как отсортировать массив данных JSON? Нравится:

let keywords = [
  { word: 'melon', occurrences: 2 },
  { word: 'apple', occurrences: 1 },
  { word: 'pear', occurrences: 4 },  
  { word: 'orange', occurrences: 2},
  { word: 'plum', occurrences: 1 }
];

Это список ключевых слов, присвоенных массиву статей. Значение occurrences указывает, скольким статьям назначено ключевое слово. Например, pear очень популярный, он есть в 4 статьях.

Если мы хотим отсортировать список только по полю word, вот простой трюк: Array.sort() может принимать функцию в качестве аргумента.

keywords = keywords.sort((a, b) => {
  if (a < b) return -1;
  if (a > b) return 1;
  return 0;
});

Это можно сократить с помощью «оператора Элвиса»:

keywords = keywords.sort((a, b) => {
  return (a < b) ? -1 : 1;
});

Или, если совсем коротко:

keywords = keywords.sort((a, b) => a < b ? -1 : 1);

Но что, если мы хотим упорядочить наш массив по обоим полям? То есть не только отсортировать по word, но и сгруппировать результаты по occurrence, чтобы ключевые слова с наибольшим количеством вхождений оставались вверху нашего списка?

Вот как.

keywords = keywords.sort((a, b) => {
  let retval = 0;
  if (a.occurrences > b.occurrences)
    retval = -1;
  if (a.occurrences < b.occurrences)
    retval = 1;
  if (retval === 0)
    retval = a.keyword < b.keyword ? -1 : 1;
  return retval;
});

Что тут происходит?

Функция, переданная Array.sort(), определяет, как два отдельных элемента массива должны сравниваться друг с другом. Любые два элемента, проходящие через функцию, при этом названные довольно нетворчески a и b, будут сравниваться, и если a должно стоять перед b, функция возвращает -1, если после него 1. 0 означает, что сортировки не будет, поэтому порядок элементов принимается таким, какой он есть. Array.sort() выполнит остальную работу и пройдется по нашему массиву, чтобы выполнить сравнение для каждого его элемента. То, что мы здесь делаем, в значительной степени является скриптом внутри скрипта.

Когда функция запускается, она создает возвращаемую переменную со значением 0.

Затем он проверяет, больше или меньше a.occurrences, чем b.occurrences. Строка с melon будет предшествовать apple, потому что первая имеет значение 2, а вторая 1.

Но если две строки имеют одинаковое количество occurrences, возвращаемое значение останется равным 0. В этом случае они будут отсортированы по word в алфавитном порядке.

Это будет наш результат:

let keywords = [
  { word: 'pear', occurrences: 4 },
  { word: 'melon', occurrences: 2 },
  { word: 'orange', occurrences: 2},
  { word: 'apple', occurrences: 1 },
  { word: 'plum', occurrences: 1 }
];

Вот в чем хитрость: сделайте сравнение на основе одного поля. Если между элементами в этом поле нет разницы, поэтому возвращаемое значение равно 0, повторите это со следующим полем (если оно есть, поскольку в этом примере их только два). Наконец, если возвращаемое значение по-прежнему равно 0 после последнего, выполните окончательное сравнение.