6
$\begingroup$

For this data:

dt = <|"a"-> <|"x"-> 1|>,"b"-> <|"y"-> 2|>,"c"-> <|"z"->3|>|>

It’s awkward when mapping the same function to multiple locations:

dt // Query[{"a" -> {"x" -> Framed}}]

When applying the same function at multiple sites, syntax gets long:

dt // Query[{"a" -> {"x" -> Framed}}] // Query[{"b" -> {"y" -> Framed}}]

In larger datasets the problem compounds. Is there a workaround for shortcuts like this:

dt // Query[{All -> {All -> Framed}}]

And also with Lists, and Span

dt // Query[{All -> {(1;;2) -> Framed}}]

as well as with hybrids of List and Associations.

PS - Even the nested parentheses are a pain for deeply nested data (we routinely deal with 6 levels or more), mitigated by this helper:

queryAt[seq__] := Query[Fold[Rule /* Reverse /* List, Reverse[{seq}]]];

eg

 queryAt["a", "x", Framed]
$\endgroup$
  • $\begingroup$ dt // Query[All, All, Framed] should work. $\endgroup$ – JungHwan Min Jun 1 '16 at 19:44
  • $\begingroup$ @JHM, only in the special case where it's mapped to All leaves, versus at specific branches, eg dt // Query["a", All, Framed] projects out the other branches. $\endgroup$ – alancalvitti Jun 1 '16 at 20:09
  • $\begingroup$ MapAt[Framed, {"a", "x"}]@dt $\endgroup$ – chuy Jun 1 '16 at 20:41
  • $\begingroup$ @chuy, I don't want to mention "x" explicitly. This will also work MapAt[Framed, {{"a", "x"}, {"b", "y"}}]@dt but need it to work across a Span or All keys at lower level. $\endgroup$ – alancalvitti Jun 1 '16 at 20:46
  • $\begingroup$ @Kuba, help me rephrase Q if necessary, but it's not about dropping a bracket - queryAt does that. It's about substituting All or Span instead of named keys. $\endgroup$ – alancalvitti Jun 1 '16 at 20:49
4
$\begingroup$

You can use Replace and Tuples to expand a Part specification in MapAt so it behaves as needed with Span.

expandedPart[rules__] :=
 Tuples[Replace[{Span[r__] :> Range[r], (t_ /; Head[t] =!= List) -> List[t]}] /@ {rules}]

This expands a Part specification.

expandedPart[1 ;; 3 ;; 2, All]
(* {{1, All}, {3, All}} *)

Now with MapAt

MapAt[Framed, expandedPart[1 ;; 3 ;; 2, All]]@dt

Mathematica graphics

or

MapAt[Framed, expandedPart[{"a", "c"}, All]]@dt

Mathematica graphics

Hope this helps.

$\endgroup$
  • $\begingroup$ @alancalvitti Note that relative from end specifications like -4;;-2 will work with the above but not open mixed relative from start and end like ;;-2 or 1;;-2. $\endgroup$ – Edmund Jun 2 '16 at 0:51

Your Answer

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

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