Проверка наличия подстроки в строке JavaScript: эффективный метод

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Чтобы определить, присутствуют ли в строке элементы из заданного списка подстрок, вы можете использовать методы some() и includes() в JavaScript:

JS
Скопировать код
const hitTest = ['яблоки', 'апельсины'].some(sub => 'прогулка в отделе апельсинов'.includes(sub));
// возвращает true, так как слово 'апельсины' найдено!
Кинга Идем в IT: пошаговый план для смены профессии

Обработка граничных ситуаций и масштабируемость

Учет граничных случаев

Рассмотрим несколько нетривиальных случаев, в которых простой подход может не дать ожидаемых результатов:

  1. Пустые строки: Не забывайте, что пустая подстрока теоретически присутствует в любой позиции вашей основной строки.
  2. Пустые массивы: Если массив подстрок пуст, соответствия не будет.
  3. Спецсимволы в регулярных выражениях: Подстроки, содержащие символы с специальным значением в регулярных выражениях, требуют экранирования.

Оптимизация при работе с большими наборами данных

Когда дело касается обработки больших массивов данных, вопрос производительности играет ключевую роль. Существуют способы оптимизации этого процесса:

  1. Можно сокращать диапазон поиска, если известно местоположение подстрок в строке.
  2. Для решения более сложных задач могут пригодиться такие структуры данных как trie или суффиксные массивы.
  3. Тестирование различных методов решения задачи позволит выбрать наиболее подходящий.

Рассмотрим альтернативы

Есть и другие способы достижения той же цели без использования методов some() и includes():

JS
Скопировать код
// Подход с использованием indexOf
const hitTestIndex = ['яблоки', 'апельсины'].some(sub => 'прогулка в отделе апельсинов'.indexOf(sub) !== -1);
// Подход с регулярными выражениями
const pattern = new RegExp(['яблоки', 'апельсины'].join('|'));
const hitTestRegex = pattern.test('прогулка в отделе апельсинов');

Метод indexOf абсолютно схож с includes, но возвращает не булево значение, а индекс. Регулярные выражения обеспечивают возможность поиска сразу по нескольким шаблонам, улучшая тем самым эффективность поиска.

Учет чувствительности к регистру и специальных символов

Учет регистра

Если необходимо учесть возможность бескейсового поиска (независимо от регистра символов), воспользуйтесь следующим подходом:

JS
Скопировать код
const hitTestCaseInsensitive = ['яблоки', 'апельсины'].some(sub =>
  'прогулка в отделе АПЕЛЬСИНОВ'.toLowerCase().includes(sub.toLowerCase())
);
// true – регистр игнорируется, результат поиска положителен!

Обработка спецсимволов

Специальные символы в подстроках требуют участия специальных мер в процессе их обработки. Для их экранирования при использовании регулярных выражений можно задействовать следующую функцию:

JS
Скопировать код
function tameRegex(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

const substrings = ['альфа(омега)', 'wall-e'];
const tameSubstrings = substrings.map(tameRegex);
const regexPattern = new RegExp(tameSubstrings.join('|'));
const hitSpecialCharTest = regexPattern.test('текст с альфа(омега)');
// true – спецсимволы обработаны и поиск осуществлен успешно!

Визуализация

Поиск подсказок в основной строке можно описать так:

Markdown
Скопировать код
Основная строка: "Мой кот любит спать целый день"
Подстроки: ["спать", "играть", "есть"]

Процесс поиска: [🔍🟩, 🔍🟧]

Вообразите, что строка – это карта, подстроки – указания на этой карте:

Markdown
Скопировать код
🔍🟩 ("спать") – Успех! Первая подсказка найдена.
🔍🟨 ("танцевать") – Промах, наш кот не увлекается танцами.
🔍🟧 ("есть") – Вы на правильном пути, вторая подсказка обнаружена!

Задача: найти все указания на карте.

Практические примеры реализации

Определение точного совпадения

Важно не только определить наличие совпадения, но и посмотреть, какая именно подстрока обнаружена:

JS
Скопировать код
const substrings = ['яблоки', 'апельсины'];
const mainStr = 'прогулка в отделе апельсинов';
const foundSub = substrings.find(sub => mainStr.includes(sub)) || "Не найдено";
// "апельсины" – Прекрасное время для приготовления фруктового салата!

Код всегда должен работать

Чтобы лучше понять, как работает код на практике, рассмотрим практический пример:

JS
Скопировать код
// Проверим, действительно ли все работает так, как мы представляем
const substrings = ['react', 'vue', 'angular'];
const text = 'Создание пользовательского интерфейса на react интересно';
const match = substrings.some(sub => text.includes(sub));

console.assert(match === true, 'Ищем удовольствие от разработки интерфейса на react');

Вы можете запустить этот код в консоли браузера или в таких средах, как JSFiddle или CodePen для наглядной демонстрации принципа работы.

Полезные материалы

  1. String.prototype.includes() – JavaScript | MDN — Описание метода для поиска фрагментов строк.
  2. Array.prototype.some() – JavaScript | MDN — Справочная информация о методе, который проверяет соответствие каждого элемента массива данному условию.
  3. ECMAScript 6: Новые возможности: Обзор и сравнение — Обширный ресурс по нововведениям в JavaScript, включая стрелочные функции, let и const.
  4. Простое объяснение замыканий в JavaScript | by Prashant Ram | Medium — Упрощённое изложение замыканий в JavaScript, которые важны при работе с обратными вызовами.
  5. Методы массивов в JavaScript — Детальное руководство по методам массивов в JavaScript.
  6. Регулярные выражения :: На пути к пониманию JavaScript — Введение в регулярные выражения для эффективного сопоставления строк.
  7. Когда (и почему) следует использовать стрелочные функции ES6 — и когда это не рекомендуется — Детальный анализ стрелочных функций ES6 и рассмотрение их применения для создания компактного и эффективного кода.