JavaScript | Как найти чётное число в строке?

Есть строка:

let stroka = '23 cтроителя из бригады 15.0 залили 604,8 м бетона из необходимых 1042 м. Это -36 м от нормы.'

В этой строке есть 4 числа:

23
15.0
604,8
1042
-36

Нам нужно определить какое из них чётное.

Логика решения задачи

На самом первом этапе нужно определиться, какую часть символов из строки мы будем считать числом. Предлагаю учитывать любую последовательность из символов — «0123456789,.-«.

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

 

Поиск чисел-строк через регулярное выражение

Мы создадим регулярное выражение. Оно будет сопоставляться глобально по всей строке при помощи метода [Symbol.match]. Внутри шаблона регулярного выражения будет жить класс символа с квантификатором.

/([0123456789,.-])+/g[Symbol.match](stroka)

Такое сопоставление вернёт нам все возможные числа в виде массива, подходящие под условие отбора.

['23', '15.0', '604,8', '1042', '.', '-36', '.']

Теперь полученные результаты нам нужно отфильтровать. Нам не нужны числа, которые оканчиваются на нечётные цифры, а также нам не нужны числа, которые имеют точку или запятую. (в этой задаче мы делаем так, потому что не ожидаем увидеть числа 14.00 или 14,00)

Внутри фильтра будет работать функция с таким условием:

!i.includes(/[.,]|[^02468]$/g.exec(i))

Мы пробрасываем в неё элемент массива i, у которого проверяется вхождение на символы [.,] и отсутствие вхождения [^02468].

Почему отрицание на возврате includes()? Всё дело в работе метода exec()

/[.,]|[^02468]$/g.exec('23')
['3', index: 1, input: '23', groups: undefined]
/[.,]|[^02468]$/g.exec('15.0')
['.', index: 2, input: '15.0', groups: undefined]
/[.,]|[^02468]$/g.exec('604,8')
[',', index: 3, input: '604,8', groups: undefined]
/[.,]|[^02468]$/g.exec('1042')
null

По таким условия подходящие нам числа (которые строки) будут возвращать null после вызова exec(). На одном из этапов работы метода filter() срабатывает приведение к логическому типу Boolean().

Boolean(null)
false
Boolean(',')
true

Приведение null к логическому типу даёт false, но во всех найденных сопоставлениях будет true. Это значит, что для возврата нужного нам значения нужно поменять истину на ложь и ложь на истину, чтобы фильтр корректно отработал.

На выходе мы имеем:

/([0123456789,.-])+/g[Symbol.match](stroka).filter(i=>!i.includes(/[.,]|[^02468]$/g.exec(i)))
['1042', '-36']

 

 

Информационные ссылки

 

Поделись записью