3
$\begingroup$

I am looking to expand this post, How can a key be renamed in an Association?.

I would like a function that automatically replaces any and all keys with the rule.

Here is what I have so far

KeyReplace[data_, rule_] := KeyMap[Replace[#, rule] &, data];
KeyReplace[data_, {rules__}] := KeyMap[Replace[#, {rules}] &, data];
KeyReplace[data_List, rule_] := KeyReplace[#, rule] & /@ data;
KeyReplace[data_List, {rules__}] := KeyReplace[#, {rules}] & /@ data;
KeyReplace[data_Association, rule_, depth_: 1] := MapAt[KeyReplace[#, rule] &, data, {depth, All}];
KeyReplace[data_Association, {rules__}, depth_: 1] := MapAll[KeyReplace[#, rules] &, data, {depth, All}];

test=<|"key1" -> <|"val11" -> val11, "val12" -> val12|>, "key2" -> {<|"val21" -> val21, "val22" -> val22|>, <|"val31" -> val31, "val32" -> val32|>}|>;

This works for the everything except the "val11" and "val12" keys.

The function should just take in any data structure and then replace the keys that match the pattern.

KeyReplace[test,"vall11"-> "new"]
(*<|"key1" -> <|"new" -> val11, "val12" -> val12|>, "key2" -> {<|"test" -> val21, "val22" -> val22|>, <|"val31" -> val31, "val32" -> val32|>}|>*)

KeyReplace[test,{"vall11"-> "new","val32"-> "new2"}]
(*<|"key1" -> <|"new" -> val11, "val12" -> val12|>, "key2" -> {<|"test" -> val21, "val22" -> val22|>, <|"val31" -> val31, "new2" -> val32|>}|>*)

KeyReplace[test,"val32"-> "new2"]
(*<|"key1" -> <|"vall11" -> val11, "val12" -> val12|>, "key2" -> {<|"test" -> val21, "val22" -> val22|>, <|"val31" -> val31, "new2" -> val32|>}|>*)

This is as close as I could get but could not get the first association to replace keys.

$\endgroup$

1 Answer 1

4
$\begingroup$

How does this work for you?

keyReplace[assoc_?AssociationQ, rules_] :=
 MapAt[
  KeyMap[Replace[rules]],
  assoc,
  Position[assoc, _?AssociationQ]
];

Try it out:

assoc = AssociationThread[
  Range[6],
  {
   <|"a" -> 1, 3 -> "x", "c" -> {1}|>,
   <|"a" -> 2, "b" -> "y", "c" -> {2, 3}|>,
   <|"a" -> 3, "b" -> "z", "c" -> {3}|>,
   <|4 -> 4, "b" -> "x", "c" -> {4, 5}|>,
   <|"a" -> 5, "b" -> "y", "c" -> {5, 6, 7}|>,
   <|"a" -> 6, "b" -> "z", "c" -> {}|>
  }
];
keyReplace[assoc, i_Integer :> i + 1]
$\endgroup$
1
  • $\begingroup$ Thank you. I knew there was a better way. Now only define it once instead of 6 times. $\endgroup$
    – Ray Troy
    Commented Feb 24, 2018 at 1:36

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.