Wolfram mathematica 从货舱中提取物品的危险性';d表达式

Wolfram mathematica 从货舱中提取物品的危险性';d表达式,wolfram-mathematica,Wolfram Mathematica,假设我有一个param->value规则列表,其中param是可能有值分配给它们的符号。例如: {a, b, c} = {1, 2, 3}; x = Hold[{a->1, b->2, c->3}]; 我需要将列表包装在Hold中,否则它将计算为{1->1,2->2,3->3}。(如果这能让剩下的事情变得更容易,我愿意接受任何其他选择。) 现在假设我想把x转换成: {"a"->1, "b"->2, "c"->3} 以下功能将执行此操作: f[h_] :=

假设我有一个param->value规则列表,其中param是可能有值分配给它们的符号。例如:

{a, b, c} = {1, 2, 3};
x = Hold[{a->1, b->2, c->3}];
我需要将列表包装在Hold中,否则它将计算为{1->1,2->2,3->3}。(如果这能让剩下的事情变得更容易,我愿意接受任何其他选择。)

现在假设我想把x转换成:

{"a"->1, "b"->2, "c"->3}
以下功能将执行此操作:

f[h_] := Block[{a,b,c}, ToString[#[[1]]]->#[[2]]& /@ ReleaseHold@h]
我的问题:你能写一个f的版本,其中符号列表{a,b,c}不需要显式提供吗

{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
输出:

也许不是很优雅,但似乎很管用。

以下是一种使用方法:


这是一个古老的问题,但我认为有一个答案结合了和的优点。您确实希望在左侧有
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
并协调一致:

In[3]:= f[rules_] :=
         Replace[rules,
          HoldPattern[Verbatim[HoldPattern][s_Symbol] -> rhs_] :>
           With[{string = ToString[Unevaluated[s]]},
            string -> rhs], {1}]
如果
rhs
本身就是一个规则或规则列表,那么
Replace
上的级别规范就是为了确保不会发生意外情况

In[4]:= f[x] // InputForm
Out[4]= {"a" -> 1, "b" -> 2, "c" -> 3}

类似这样的东西似乎几乎可以工作:
Block[Names[“Global
*”],…`谢谢!我担心
StringTake[…,{6,-2}]
。这对长变量名和规则右侧的任意内容有多强?哦,只是提取其中的任何内容吗[…]?也许这足够安全。@dreeves SymbolName[]返回一个字符串,因此我认为任何符号都可以安全地视为字符串……是的,它只是用于退出Hold[]参数。@dreeves规则的rhs保持不变。lhs是Hold[SymbolName]事情,所以我想使用SymbolName而不是ToString是安全的。我很好奇是否有很多理由选择其中一个。@dreeves这很有趣。根据帮助,“SymbolName总是给出没有任何上下文的短名称。ToString考虑了$context和$ContextPath的设置”。
In[3]:= f[rules_] :=
         Replace[rules,
          HoldPattern[Verbatim[HoldPattern][s_Symbol] -> rhs_] :>
           With[{string = ToString[Unevaluated[s]]},
            string -> rhs], {1}]
In[4]:= f[x] // InputForm
Out[4]= {"a" -> 1, "b" -> 2, "c" -> 3}