Как сортировать массив объектов по тому, насколько целевая строка близка в определенном свойстве каждого объекта?

У меня есть целевая строка, в данном примере - foo.

И у меня есть массив объектов, у каждого из них есть текстовое свойство, которое может содержать целевую строку.

Массив такого вида:

let array = [{
  name: "BarFoo",
  num: 20
}, {
  name: "FooBar",
  num: 10
}, {
  name: "FooFoo",
  num: 0
}, {
  name: "NotBar",
  num: 0
}]

Мне необходимо отсортировать массив не только по количеству совпадений целевой строки в свойстве name, а еще и по тому, насколько целевая строка ближе к началу(FooBar > BarFoo, хотя в массиве второй стоит первее)

И все остальные объекты, в которых нет совпадений - по алфавиту.

Суммирую вопрос:

Как мне сортировать массив объектов исходя из такой приоритетности:

  1. Количество совпадений целевой строки в строке значения name
  2. Насколько далеко целевая строка от начала name
  3. Если отсутствует целевая строка - сортировать по алфавиту.

?

UPD. Перед сортировкой все значения будут перенесены lowerCase


Ответы (1 шт):

Автор решения: mego4iter

Вы сами уже всё решили, осталось только воспользоваться функцией sort

let array = [
  {
    name: "BarFoo",
    num: 20
  },
  {
    name: "FooBar",
    num: 10
  },
  {
    name: "FooFoo",
    num: 0
  },
  {
    name: "NotBar",
    num: 0
  }
];

function sortByInclude(text) {
  return function(a, b) {
    // Кол-во вхождений
    const includeA = a.name.split(text).length - 1;
    const includeB = b.name.split(text).length - 1;
    if (includeA !== includeB) {
      return includeA < includeB ? 1 : -1;
    }
    // Удалённость от начала строки
    const idxA = a.name.indexOf(text);
    const idxB = b.name.indexOf(text);
    if (idxA !== idxB) {
      return idxA < idxB ? -1 : 1;
    }
    // По алфовиту
    return a.name.localeCompare(b.name);
  };
}

console.log(array.sort(sortByInclude("Foo")));

→ Ссылка