Considering an association:
<|"a" -> <|aa-> "asc", bb-> "asd", cc-> 0, ImageType -> "asd", dd-> "asd"|>|>
How can I make the inner keys strings?
<|"a" -> <|"aa"-> "asc", "bb"-> "asd", "cc"-> 0, "ImageType" -> "asd", "dd"-> "asd"|>|>
Considering an association:
<|"a" -> <|aa-> "asc", bb-> "asd", cc-> 0, ImageType -> "asd", dd-> "asd"|>|>
How can I make the inner keys strings?
<|"a" -> <|"aa"-> "asc", "bb"-> "asd", "cc"-> 0, "ImageType" -> "asd", "dd"-> "asd"|>|>
assoc= <|"a" -> <| aa-> "asc", bb->"asd", cc->0, ImageType->"asd", dd-> "asd"|>|>;
KeyMap[ToString]/@assoc
(* <|"a" -> <|"aa" -> "asc", "bb" -> "asd", "cc" -> 0,
"ImageType" -> "asd", "dd" -> "asd"|>|> *)
Update:
but what if I have n levels?
I hope there is a better/cleaner way to deal with nested associations than the following:
assoc2= <| a-> <| aa-> "asc", bb->"asd", cc->0, ImageType->"asd",
dd-> <|dd1->"asd", dd2->"asd2"|>|>|>;
Replace[assoc2/. Association->foo, Rule[a_,b_]:>Rule[ToString[a],b],
{0,Infinity}]/. foo->Association
(* <|"a" -> <|"aa" -> "asc", "bb" -> "asd", "cc" -> 0,
"ImageType" -> "asd",
"dd" -> <|"dd1" -> "asd", "dd2" -> "asd2"|>|>|> *)
Interestingly, not any of the association *Map
(KeyMap
, AssociationMap
, KeyValueMap
) functions accept a third argument for level specification. One can use Replace
but with an extra Evaluate
, as the replacement does not evaluate the KeyMap
function:
ass = <|a -> <|aa -> "aa", ab -> <|ab1 -> "x", ab2 -> "y"|>|>|>;
Replace[ass, a_Association :> (Evaluate /@ KeyMap[ToString, a]), {0, Infinity}]
<|"a" -> <|"aa" -> "aa", "ab" -> <|"ab1" -> "x", "ab2" -> "y"|>|>|>
Without the forced evaluation, ToString
is applied but not evaluated:
Replace[ass, a_Association :> KeyMap[ToString, a], {0, Infinity}]
<|"a" -> KeyMap[ToString, <|aa -> "aa", ab -> KeyMap[ToString, <|ab1 -> "x", ab2 -> "y"|>]|>]|>
(version 10.1, Win7 64)
Association
is not meant to be a single-level vector, even the documentation has many nested examples, so I wonder.
$\endgroup$
Commented
Apr 12, 2015 at 16:46
A derivative of István's answer:
asc = <|"a" -> <|aa -> "asc" + "zzz", bb -> "asd", cc -> 0, ImageType -> "asd",
dd -> "asd"|>|>;
AssociateTo[asc, "foo" -> asc];
fn[a_Association] := KeyMap[ToString, a]
fn[else_] := else
fn //@ asc // InputForm
<|"a" -> <|"aa" -> "asc" + "zzz", "bb" -> "asd", "cc" -> 0, "ImageType" -> "asd", "dd" -> "asd"|>, "foo" -> <|"a" -> <|"aa" -> "asc" + "zzz", "bb" -> "asd", "cc" -> 0, "ImageType" -> "asd", "dd" -> "asd"|>|>|>