4
$\begingroup$

I want to create a List of Associations from data in a two-dimensional List by using ReplaceAll, but did not manage to produce the expected result.

So here is a short example, the original lists are stored in the variable values:

values = {{1, a}, {2, b}, {3, c}}
{{1, a}, {2, b}, {3, c}}

and I want to transform this to a List of Associations with Keys "N" and "C" for the numbers and the characters

{<|"N" -> 1, "C" -> a|>, <|"N" -> 2, "C" -> b|>, <|"N" -> 3, "C" -> c|>}

If I use the ReplaceAll command to create an Association I do not get the desired result

values /. {num_, char_} -> <|"N" -> num, "C" -> char|>
{<|"N" -> num, "C" -> char|>, <|"N" -> num, "C" -> char|>, <|"N" -> num, "C" -> char|>}

So the values for num and char are not considered correctly in ReplaceAll. However, If I would replace the Association by a List of Rules this works:

values /. {num_, char_} -> {"N" -> num, "C" -> char}
{{"N" -> 1, "C" -> a}, {"N" -> 2, "C" -> b}, {"N" -> 3, "C" -> c}}

Is there any explanation why the behaviour is different for the Association? What is the usual way to create Associations from Lists?

$\endgroup$
1
  • $\begingroup$ Okay, I just found out that using :> (RuleDelayed) instead of -> (Rule) in ReplaceAll does the trick. Is there any explanation why? So the working command is values /. {num_, char_} :> <|"N" -> num, "C" -> char|> $\endgroup$
    – Mathias
    Commented Jan 21, 2022 at 13:29

1 Answer 1

8
$\begingroup$

If you use "Rule" the right side is evaluated at once resulting in:

{<|"N" -> num, "C" -> char|>, <|"N" -> num, "C" -> char|>, <|"N" -> num, "C" -> char|>}

On the other hand, if you use RuleDelayed, the right side is only evaluated when the pattern has matched:

values = {{1, a}, {2, b}, {3, c}};
values /. {num_, char_} :> <|"N" -> num, "C" -> char|>
(*{<|"N" -> 1, "C" -> a|>, <|"N" -> 2, "C" -> b|>, <|"N" -> 3, "C" -> c|>} *)
$\endgroup$
4
  • 1
    $\begingroup$ But why is there no problem when using a List instead of an Association on the right hand side? $\endgroup$
    – Mathias
    Commented Jan 21, 2022 at 13:44
  • 2
    $\begingroup$ The reason is that Association has the attribute HoldAllComplete. $\endgroup$ Commented Jan 21, 2022 at 13:52
  • $\begingroup$ I don't think that is true, after all HoldComplete also has that attribute yet n is substituted in 1 /. n_ -> HoldComplete[n]. I believe the cause is the fact that association constructor expressions evaluate to atomic association objects (see Evaluated vs. unevaluated Association). $\endgroup$
    – WReach
    Commented Jan 21, 2022 at 21:46
  • $\begingroup$ Thank's. There is always new to learn.. $\endgroup$ Commented Jan 22, 2022 at 9:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.