Подтвердить что ты не робот

Согласование конечного диапазона элементов с шаблонами

Во время моего ответа на этот question мне пришло в голову, что трудно сопоставить конечный диапазон элементов. Со встроенными шаблонами вы можете сопоставить 1 элемент (_), 1 или более элементов (__) или ноль или более элементов (___). Чтобы сопоставить более одного элемента, я использовал PatternSequence, как этот

a:PatternSequence[_,_,_]

или, более общий

a:[email protected]@Array[_&,3].

(Используя Condition, также работал.) Чтобы соответствовать диапазону от n до m элементов, мы могли бы сделать

a:[email protected]@( PatternSequence @@@ Array[_&, {n,m}] ),

но это довольно запутанный способ выполнить что-то, что можно сделать с помощью

a__ /; n <= Length[{a}] <= m.

Однако это вызывает интересный вопрос, используя формулу Condition, она проста в соответствии с диапазоном от 0 до n,

a___ /; Length[{a}] <= n,

но может ли это быть сделано с использованием шаблонов в одиночку, т.е. без использования Condition (/;)? Более конкретно, как можно было бы сопоставить 0 элементов без добавления условия? Кроме того, что быстрее?

4b9b3361

Ответ 1

Возможно, вы могли бы что-то сделать с помощью Repeated. Например.

Cases[{{1, 2, 3}, {1}, {1, 2, 3, 4, 5}, {1,2}}, {Repeated[_, {2, 4}]}]

дает тот же результат, что и

Cases[{{1, 2, 3}, {1}, {1, 2, 3, 4, 5}, {1,2}}, {a___ /; 2 <= Length[{a}] <= 4}]

Первый метод кажется быстрее второго. Например

tab = Table[Range[RandomInteger[1000]], {1000}];
Timing[t1 = Cases[tab, {a___ /; 0 <= Length[{a}] <= 100}];]
Timing[t2 = Cases[tab, {Repeated[_, {0, 100}]}];]
SameQ[t1, t2]

возвращает мою систему

{0.027801, Null}

{0.000733, Null}

True