Вы можете использовать includes
, который проверит наличие значения в массиве, а затем вернет истину или ложь ...
var arr = [1,4,7];
var added = 4;
if(!arr.includes(added)) {
arr.push(added);
}
console.log(arr);
Используя DFA здесь , мы можем создать регулярное выражение следующим образом, где A, B, C представляют состояния DFA.
A = 1B + 0A
B = 1A + 0C
C = 1C + 0B
C = 1*0B // Eliminate recursion
B = 1A + 0(1*0B)
B = 01*0B + 1A
B = (01*0)*1A // Eliminate recursion
A = 1(01*0)*1A + 0A
A = (1(01*0)*1 + 0)A
A = (1(01*0)*1 + 0)* // Eliminate recursion
В результате получается PCRE. регулярное выражение вида:
/^(1(01*0)*1|0)+$/
Perl test / example:
use strict;
for(qw(
11
110
1001
1100
1111
0
1
10
111
)){
print "$_ (", eval "0b$_", ") ";
print /^(1(01*0)*1|0)+$/? "matched": "didnt match";
print "\n";
}
Выводит:
11 (3) matched
110 (6) matched
1001 (9) matched
1100 (12) matched
1111 (15) matched
0 (0) matched
1 (1) didnt match
10 (2) didnt match
111 (7) didnt match
Не думаю, что вы бы стали. Я не могу поверить, что какой-либо язык, использующий регулярные выражения, может быть лучшим способом сделать это.
Когда вы делите число на три, остается только три возможных остатка (0, 1 и 2). Ваша цель - убедиться, что остаток равен 0, а значит, кратен трем.
Это может быть сделано автоматом с тремя состояниями:
Теперь представьте любое неотрицательное число (это наша область) и умножьте его на два (прибавьте двоичный ноль к концу). Переходы для этого следующие:
ST0 -> ST0 (3n * 2 = 3 * 2n, still a multiple of three).
ST1 -> ST2 ((3n+1) * 2 = 3*2n + 2, a multiple of three, plus 2).
ST2 -> ST1 ((3n+2) * 2 = 3*2n + 4 = 3*(2n+1) + 1, a multiple of three, plus 1).
Также подумайте о любом неотрицательном числе, умножьте его на два, затем добавьте единицу (добавьте двоичное число в конец). Переходы для этого следующие:
ST0 -> ST1 (3n * 2 + 1 = 3*2n + 1, a multiple of three, plus 1).
ST1 -> ST0 ((3n+1) * 2 + 1 = 3*2n + 2 + 1 = 3*(2n+1), a multiple of three).
ST2 -> ST2 ((3n+2) * 2 + 1 = 3*2n + 4 + 1 = 3*(2n+1) + 2, a multiple of three, plus 2).
Идея состоит в том, что в конце вам нужно завершить работу в состоянии ST0. Тем не мение, учитывая, что может быть произвольное количество подвыражений (и подвыражений), его нелегко свести к регулярному выражению.
Что вам нужно сделать, так это разрешить любую из последовательностей переходов которые могут перейти от ST0 к ST0, а затем просто повторить их:
Они сводятся к двум последовательностям RE:
ST0 --> ST0 : 0+
[0]
ST0 --> ST1 (--> ST2 (--> ST2)* --> ST1)* --> ST0: 1(01*0)*1
[1] ([0] ([1] )* [0] )* [1]
или регулярному выражению:
(0+|1(01*0)*1)+
Это захватывает числа, кратные трем, или, по крайней мере, первые десять, которые я тестировал , Вы можете пробовать сколько угодно, все они сработают, в этом прелесть математического анализа, а не анекдотические свидетельства.
Они сводятся к двум последовательностям RE:
ST0 --> ST0 : 0+
[0]
ST0 --> ST1 (--> ST2 (--> ST2)* --> ST1)* --> ST0: 1(01*0)*1
[1] ([0] ([1] )* [0] )* [1]
или регулярному выражению:
(0+|1(01*0)*1)+
Это захватывает числа, кратные трем, или, по крайней мере, первые десять, которые я тестировал. Вы можете пробовать сколько угодно, все они сработают, в этом прелесть математического анализа, а не анекдотические свидетельства.
Они сводятся к двум последовательностям RE:
ST0 --> ST0 : 0+
[0]
ST0 --> ST1 (--> ST2 (--> ST2)* --> ST1)* --> ST0: 1(01*0)*1
[1] ([0] ([1] )* [0] )* [1]
или регулярному выражению:
(0+|1(01*0)*1)+
Это захватывает числа, кратные трем, или, по крайней мере, первые десять, которые я тестировал. Вы можете пробовать сколько угодно, все они сработают, в этом прелесть математического анализа, а не анекдотические свидетельства.