Задать вопрос
RatiboR1978
@RatiboR1978

Как сделать такую сортировку?

Доброе время суток! Изучаю js вот застрял с такой задачей: Дан массив со словами. Отсортируйте его следующим образом: первое слово должно быть первым по алфавиту, следующее за ним слово должно начинаться на ту букву, на которую заканчивается первое слово или, если такого слова в массиве нет, должно начинаться на ближайшую по алфавиту букву.
К примеру, первое слово заканчивается на "а", значит второе слово должно начинаться на "а", или на "б", если слов на "а" нету. И так далее.
Вот мой код: https://codepen.io/RatiboR1978/pen/WKXBOx?editors=1010 я реализовал то что в массиве набираются слова у которых последняя буква первого слова совпадает с первой буквой второго слова, но не могу додуматься как сделать когда берется уже не первая буква второго слова а последующие. Не знаю понятно объяснил или нет. Прошу помощи.
  • Вопрос задан
  • 269 просмотров
Подписаться 3 Простой 2 комментария
Решения вопроса 2
Stalker_RED
@Stalker_RED
Для начала алфавит:
let alphabet = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя'.split('')
charcode использовать нельзя, потому что в юникоде буква "ё" идет после буквы "я". И это, похоже, навсегда.

Дальше функция, которая определяет "расстояние" между буквами.
function getRange(a, b) {
  let iA = alphabet.indexOf(a), iB = alphabet.indexOf(b) // ищем на каких позициях встречаются эти буквы в алфавите
  if (iA === -1 || iB === -1) return Infinity // если вообще не встречаются - расстояние бесконечность.
  return Math.abs(iA - iB)
}


getRange('а', 'р') // -> 17
getRange('а', 'я') // -> 32
getRange('к', 'в') // -> 9
getRange('а', 'f') // -> Infinity  (и никто не мешает добавить английский алфавит)


На основе этой функции не сложно написать сортировку по расстоянию:
function getClosestWord(letter) {
  return [...words].sort((word1, word2) => {
  	return getRange(word1[0], letter) - getRange(word2[0], letter)
  })
}

getClosestWord('а') // ->
["аметист", "баржа", "дом", "еж", "креветка", "каток", "кот", "лимон", "море", "морж", "нора", "рога", "рыба", "рак", "сани", "сом", "собака", "том", "танк"]

getClosestWord('п') // ->
["рыба", "рак", "рога", "нора", "собака", "сани", "сом", "танк", "море", "том", "морж", "лимон", "каток", "кот", "креветка", "еж", "дом", "баржа", "аметист"]


Дело за малым - повторять пока не закончатся слова.
Ответ написан
Комментировать
0xD34F
@0xD34F Куратор тега JavaScript
function sorted(arr) {
  const chars = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя';
  const words = arr.filter(n => chars.includes(n[0]) && chars.includes(n.slice(-1)));
  const grouped = words.reduce(
    (acc, n) => (acc[chars.indexOf(n[0])].push(n), acc),
    Array.from(chars, () => [])
  );

  const result = [];

  for (
    let prev = (grouped.find(n => n.length) || []).pop();
    prev && result.push(prev) < words.length;
  ) {
    for (
      let i = chars.indexOf(prev.slice(-1)), j = i;
      !(prev = grouped[i].pop() || grouped[j].pop());
      i = -~i % grouped.length, j = ~-(j || grouped.length)
    ) ;
  }

  return result;
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы