4
$\begingroup$

Is there a general and terse method to obtain the parent key of the current "position" in a Query of an Association/Dataset?

Say I have the following Association.

assoc =
 <|"A" ->
    <|"a" -> <|"one" -> 1, "two" -> 2, "three" -> 3|>,
      "b" -> <|"one" -> 1, "two" -> 2, "three" -> 3|>|>,
   "B" ->
    <|"c" -> <|"four" -> 4, "five" -> 5, "six" -> 6|>,
      "d" -> <|"four" -> 4, "five" -> 5, "six" -> 6|>|>
 |>

It is easy to get a position's child keys with KeyValueMap.

Query[All, Association@KeyValueMap[#1 -> f[#1, Keys@#2] &]]@assoc
<|"A" -> <|"a" -> f["a", {"one", "two", "three"}], 
           "b" -> f["b", {"one", "two", "three"}]|>, 
  "B" -> <|"c" -> f["c", {"four", "five", "six"}], 
           "d" -> f["d", {"four", "five", "six"}]|>
|>

However, to get the parent key a nesting of KeyValueMap is used.

Association@Query[
   KeyValueMap[
    Function[{parent, child},
     parent ->
      Association @@ KeyValueMap[#1 -> f[parent, #1] &]@child
     ]
    ]]@assoc
<|"A" -> <|"a" -> f["A", "a"], "b" -> f["A", "b"]|>, 
  "B" -> <|"c" -> f["B", "c"], "d" -> f["B", "d"]|>
|>

And

Association@Query[
   KeyValueMap[
    Function[{parent, child},
     parent ->
      Association @@ KeyValueMap[f[parent, #1] -> #2 &]@child
     ]
    ]]@assoc
<|"A" -> 
   <|f["A", "a"] -> <|"one" -> 1, "two" -> 2, "three" -> 3|>, 
     f["A", "b"] -> <|"one" -> 1, "two" -> 2, "three" -> 3|>|>, 
  "B" -> 
   <|f["B", "c"] -> <|"four" -> 4, "five" -> 5, "six" -> 6|>, 
     f["B", "d"] -> <|"four" -> 4, "five" -> 5, "six" -> 6|>|>
|>

This seems to be a lot of effort for what should be an easy task for a hierarchical structure.

Am I completely doing this wrong? Is there built-in support for getting a position's parent key?

$\endgroup$
7
  • $\begingroup$ You could do things like this: MapIndexed[f @@ Map[First, #2] &, assoc, {2}]. But in general, since assocs are immutable, they don't store references to their parents (because they don't have parents, in a sense), so it should be expected that going "up" is harder than going "down". $\endgroup$ May 1 '17 at 17:15
  • $\begingroup$ @LeonidShifrin What about the case of Dataset[assoc]? Is there some way with that since it is an hierarchical object by design? $\endgroup$
    – Edmund
    May 1 '17 at 17:19
  • $\begingroup$ Not as far as I know. You may generate an actual query and look at it (Dataset`CompileQuery), perhaps things like MapIndexed would also just work there, but there isn't any built-in Dataset - level mechanism to reference parents, AFAIK. $\endgroup$ May 1 '17 at 17:22
  • $\begingroup$ @LeonidShifrin I suppose Map[Association@*Values, #, {1}] &@ MapIndexed[f[Sequence @@ Map[First, #2]] -> #1 &, assoc, {2}] for the second case. Still very verbose considering Dataset is a hierarchical object. $\endgroup$
    – Edmund
    May 1 '17 at 17:26
  • $\begingroup$ Yep, something like that. Re:verbose - I agree, the more transparent access to parent keys / positions could've been built-in. But again, immutability makes this a harder problem (while making many other things vastly simpler). $\endgroup$ May 1 '17 at 17:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.