Для начала вспомним условие задачи:

Учитывая массив (arr) в качестве аргумента, завершите функцию countSmileys, которая должна возвращать общее количество улыбающихся лиц.

Правила для смайла:

Каждый смайлик должен содержать корректную пару глаз. Глаза могут быть отмечены как : или ; — У смайлика может быть нос, но это не обязательно. Допустимыми символами для носа являются - или ~ — На каждом смайле должен быть улыбающийся рот, который должен быть отмечен либо ), либо D

Никакие дополнительные символы, кроме упомянутых, не допускаются.

Вспомним моё решение:

int countSmileys(List<String> arr) => RegExp(r'([;:][-~]?[)D])').allMatches(arr.join(',')).length;

Я выбрала, как мне кажется, простое решение — анализировать элементы массива опосредованно через регулярные выражения. Иначе нужно было бы писать циклы, смотреть на индексы, напрямую анализировать эти строки.

Что такое регулярное выражение?

Регулярное выражение (сокращенно regex или regexp) это шаблоны, последовательность специальных символов, которые определяют, как следует проверить соответствия в строках.

Регулярное выражение создается с помощью необработанной строки (raw string) — строка с префиксом r.

В решении это выглядит вот так:

RegExp(r'([;:][-~]?[)D])')

Что значат эти символы внутри скобок?

Есть отличная статья про символы в регулярных выражениях, но свой выбор я всё-таки поясню здесь.

У нас есть три определённых критерия для поиска совпадений: глаза, носы и рты. При этом глаза и рты обязательны, а носа может и не быть.

Квадратные скобки (группа) описывают набор символов, который ищет регулярное выражение на этом месте.

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

Как проверить, верно ли составлено регулярное выражение?

Я использую специальный сайт — https://www.regexpal.com/. Подобных сайтов много.

Здесь показано, как отрабатывает и ищет совпадения регулярное выражение

Здесь показано, как отрабатывает и ищет совпадения регулярное выражение

А что после регулярного выражения?

Метод *allMatches* последовательно возвращает все подстроки, которые соответствуют регулярному выражению — то есть, все совпадения.

Метод join нужен из-за условности тестов в задаче: он соединяет несколько строк в одну, используя разделитель — в моем случае это запятая.