Pattern Matching с индексированным Object


5

Если у меня есть список правил, связанные с индексированными переменными, как:

solution = {a[1] -> 1, a[2] -> 10, a[3] -> 100} 

Я хотел бы быть в состоянии извлечь все значения, связанные с правилами. Хотя эта проблема проста с небольшим числом переменных, я не уверен, как ее обобщить.

Например, можно использовать сопоставление с образцом, чтобы получить 1 и 10, соответственно:

a[1]/.solution 
a[2]/.solution 

Однако я не могу обобщить эту функцию, чтобы извлечь [N] значения из списка правил. Какова правильная схема для этого?

4

Это не то, что Rules сделаны для, но следующие работает хорошо для простых случаев:

solution[[All, 2]] 
{1, 10, 100} 

Подробнее "собственно" путь:

a /@ Range[3] /. solution 

или эквивалент предложил г-н Мастер

Array[a, 3] /. solution 

Для более вложенного списка правил, которые можно использовать Cases (но тогда вы должны держать глаза на то, что;)):

Cases[solution, (a[_] -> x_):> x, Infinity] 
{1, 10, 100} 

Или же, но в другой форме:

Cases[solution, Rule[a[_], x_] :> x, Infinity] 
Cases[solution, HoldPattern[a[_] -> x_] :> x, Infinity] 

Замечания о Cases:

  • Для примера, по умолчанию levelspec для Cases, который {1}, будет делать эту работу.
  • ReplaceAll (/.) будет работать с solution, содержащий Rule (->) или RuleDelayed (:>), но для Cases мы должны указать на это:

solution = {a[1] -> 1, a[2] :> 5, a[3] -> 100} 

Cases[solution, Rule[a[_], x_] :> x] 
Cases[solution, (Rule | RuleDelayed)[a[_], x_] :> x] 
{a[1] -> 1, a[2] :> 5, a[3] -> 100} 
{1, 100} 
{1, 5, 100} 
  0

Великого ответ. Обычно я использую, например, 'Array [a, 3]' сам, FWIW. Возможно, вы захотите рассмотреть возможность использования правил ':>' в методах 'Cases'. 26 авг. 132013-08-26 21:27:23

  0

@ Mr.Wizard Спасибо. Я видел этот вопрос, и я думал, что он будет закрыт, но я не искал дубликат или пример расширения в документации. (* Я боюсь спросить, но что вы подразумеваете под своим вторым замечанием? *) 26 авг. 132013-08-26 21:33:38

+1

Что делать, если, например, 'solution = {a [1] -> 1, a [2]:> $ var, a [3] -> 100}' - было бы неплохо хотя бы упомянуть, что это не будет обрабатываться шаблоном 'Правило [a [_], x_]:> x'. Кстати, я замечаю, что вы используете 'HoldPattern'; если это только для группировки, вы также можете использовать круглые скобки. 26 авг. 132013-08-26 21:45:17

+1

Почему не просто «решение /. (a [_] -> x_):> x' => {1, 10, 100}? 26 авг. 132013-08-26 23:26:51

  0

@TomD Хорошая точка, это похоже на 'Cases', но проще в форме, вы можете добавить этот пример в качестве ответа тоже :) 26 авг. 132013-08-26 23:39:47


3

Куба уже опубликовал естественный w ays для решения этой проблемы, так что вот неестественный один.

Вы можете временно (внутри Block) делаете определение правил для Символа a установки DownValues:

rules = 
{a[1]->76,a[2]->36,a[3]->87,a[4]->42,a[5]->52,a[6]->73,a[7]->41,a[8]->58,a[9]->79}; 

Block[{a}, DownValues[a] = rules; Array[a, 5]] 
{76, 36, 87, 42, 52}