Изысканность с извлечением вещей из выражения Hold'd - PullRequest
3 голосов
/ 20 января 2011

Предположим, у меня есть список правил param-> value, где params являются символами, которым могут быть присвоены значения. Например:

{a, b, c} = {1, 2, 3};
x = Hold[{a->1, b->2, c->3}];

Мне нужен список, заключенный в Hold, в противном случае он получит значение {1-> 1, 2-> 2, 3-> 3}. (Я открыт для любых альтернатив, чтобы Держать там, если это облегчает остальное.)

Теперь предположим, что я хочу преобразовать х в это:

{"a"->1, "b"->2, "c"->3}

Следующая функция сделает это:

f[h_] := Block[{a,b,c}, ToString[#[[1]]]->#[[2]]& /@ ReleaseHold@h]

Мой вопрос: можете ли вы написать версию f, в которой список символов {a, b, c} не нужно указывать явно?

Ответы [ 3 ]

5 голосов
/ 20 января 2011

Вот способ использования Неоцененный :

In[1]:= {a, b, c} = {1, 2, 3};

In[2]:= x = Hold[{a -> 1, b -> 2, c -> 3}];

In[3]:= ReleaseHold[
 x /. (symb_ -> e_) :> ToString[Unevaluated[symb]] -> e]

Out[3]= {"a" -> 1, "b" -> 2, "c" -> 3}
1 голос
/ 04 февраля 2011

Это старый вопрос, но я думаю, что есть ответ, который сочетает в себе достоинства ответа Эндрю Мойлана и ответа Велисария .Вы действительно хотите иметь списки правил с HoldPattern слева, а не списки правил, которые Hold обернуты вокруг всего, так что вы можете использовать правила без необходимости выполнять какие-либо действия.из ReleaseHold процесса.

In[1]:= {a, b, c} = {1, 2, 3};

Unevaluated также может быть полезен при создании списка, который вы хотите:

In[2]:= x = Thread[HoldPattern /@ Unevaluated[{a, b, c}] -> Range[3]]
Out[2]= {HoldPattern[a] -> 1, HoldPattern[b] -> 2, HoldPattern[c] -> 3}

Теперь вы можете делать то, что вы хотите, с заменой правил,Это немного вовлечено, но это то, что я делаю снова и снова.Вы можете заметить, что этот список правил имеет почти точно форму списка OwnValues или DownValues, поэтому возможность манипулировать им очень полезна.Трюк использует HoldPattern и Verbatim в согласовании:

In[3]:= f[rules_] :=
         Replace[rules,
          HoldPattern[Verbatim[HoldPattern][s_Symbol] -> rhs_] :>
           With[{string = ToString[Unevaluated[s]]},
            string -> rhs], {1}]

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

In[4]:= f[x] // InputForm
Out[4]= {"a" -> 1, "b" -> 2, "c" -> 3}
1 голос
/ 20 января 2011
{a, b, c} = {1, 2, 3};
x = Hold[{a -> 1, b -> 2, c -> 3}];
f[x_] := Cases[x, HoldPattern[z_ -> y_] :> 
                  StringTake[ToString[(Hold@z)], {6, -2}] -> y, 2];
f[x] // InputForm

Out:

{"a" -> 1, "b" -> 2, "c" -> 3} 

Возможно, не очень элегантно, но, кажется, работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...