Skip to main content
used `DeleteMissing` as per suggestion by @m_goldberg
Source Link
WReach
  • 69.3k
  • 4
  • 165
  • 272

Mathematica 10.1 almost supports this operation directly:

assoc // Query[Transpose]

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

All that remains is to delete the unwanted Missing elements:

assoc // Query[Transpose] // DeleteCases[#, _MissingDeleteMissing[#, {2}] &2]&

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

We can see that Query uses the undocumented function GeneralUtilities`AssociationTranspose to do the heavy-lifting:

Query[Transpose] // Normal

(* GeneralUtilities`AssociationTranspose *)

assoc // GeneralUtilities`AssociationTranspose

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

An Imperative Solution

The words "elegant" and "imperative" rarely appear together these days, but an imperative solution can express the transposition directly:

Module[{r = <| |>}
, Do[r = Merge[{r, <| j -> <| i -> assoc[[i, j]] |> |>}, Association]
  , {i, Keys[assoc]}
  , {j, Keys[assoc[[i]]]}
  ]
; r
]

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

A ScanIndexed operator would come in handy here (the undocumented one in GeneralUtilities` is not, well, general enough).

Mathematica 10.1 almost supports this operation directly:

assoc // Query[Transpose]

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

All that remains is to delete the unwanted Missing elements:

assoc // Query[Transpose] // DeleteCases[#, _Missing, {2}] &

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

We can see that Query uses the undocumented function GeneralUtilities`AssociationTranspose to do the heavy-lifting:

Query[Transpose] // Normal

(* GeneralUtilities`AssociationTranspose *)

assoc // GeneralUtilities`AssociationTranspose

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

An Imperative Solution

The words "elegant" and "imperative" rarely appear together these days, but an imperative solution can express the transposition directly:

Module[{r = <| |>}
, Do[r = Merge[{r, <| j -> <| i -> assoc[[i, j]] |> |>}, Association]
  , {i, Keys[assoc]}
  , {j, Keys[assoc[[i]]]}
  ]
; r
]

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

A ScanIndexed operator would come in handy here (the undocumented one in GeneralUtilities` is not, well, general enough).

Mathematica 10.1 almost supports this operation directly:

assoc // Query[Transpose]

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

All that remains is to delete the unwanted Missing elements:

assoc // Query[Transpose] // DeleteMissing[#, 2]&

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

We can see that Query uses the undocumented function GeneralUtilities`AssociationTranspose to do the heavy-lifting:

Query[Transpose] // Normal

(* GeneralUtilities`AssociationTranspose *)

assoc // GeneralUtilities`AssociationTranspose

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

An Imperative Solution

The words "elegant" and "imperative" rarely appear together these days, but an imperative solution can express the transposition directly:

Module[{r = <| |>}
, Do[r = Merge[{r, <| j -> <| i -> assoc[[i, j]] |> |>}, Association]
  , {i, Keys[assoc]}
  , {j, Keys[assoc[[i]]]}
  ]
; r
]

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

A ScanIndexed operator would come in handy here (the undocumented one in GeneralUtilities` is not, well, general enough).

added an imperative solution
Source Link
WReach
  • 69.3k
  • 4
  • 165
  • 272

Mathematica 10.1 almost supports this operation directly:

assoc // Query[Transpose]

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

All that remains is to delete the unwanted Missing elements:

assoc // Query[Transpose] // DeleteCases[#, _Missing, {2}] &

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

We can see that Query uses the undocumented function GeneralUtilities`AssociationTranspose to do the heavy-lifting:

Query[Transpose] // Normal

(* GeneralUtilities`AssociationTranspose *)

assoc // GeneralUtilities`AssociationTranspose

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

An Imperative Solution

The words "elegant" and "imperative" rarely appear together these days, but an imperative solution can express the transposition directly:

Module[{r = <| |>}
, Do[r = Merge[{r, <| j -> <| i -> assoc[[i, j]] |> |>}, Association]
  , {i, Keys[assoc]}
  , {j, Keys[assoc[[i]]]}
  ]
; r
]

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

A ScanIndexed operator would come in handy here (the undocumented one in GeneralUtilities` is not, well, general enough).

Mathematica 10.1 almost supports this operation directly:

assoc // Query[Transpose]

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

All that remains is to delete the unwanted Missing elements:

assoc // Query[Transpose] // DeleteCases[#, _Missing, {2}] &

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

We can see that Query uses the undocumented function GeneralUtilities`AssociationTranspose to do the heavy-lifting:

Query[Transpose] // Normal

(* GeneralUtilities`AssociationTranspose *)

assoc // GeneralUtilities`AssociationTranspose

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

Mathematica 10.1 almost supports this operation directly:

assoc // Query[Transpose]

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

All that remains is to delete the unwanted Missing elements:

assoc // Query[Transpose] // DeleteCases[#, _Missing, {2}] &

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

We can see that Query uses the undocumented function GeneralUtilities`AssociationTranspose to do the heavy-lifting:

Query[Transpose] // Normal

(* GeneralUtilities`AssociationTranspose *)

assoc // GeneralUtilities`AssociationTranspose

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

An Imperative Solution

The words "elegant" and "imperative" rarely appear together these days, but an imperative solution can express the transposition directly:

Module[{r = <| |>}
, Do[r = Merge[{r, <| j -> <| i -> assoc[[i, j]] |> |>}, Association]
  , {i, Keys[assoc]}
  , {j, Keys[assoc[[i]]]}
  ]
; r
]

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

A ScanIndexed operator would come in handy here (the undocumented one in GeneralUtilities` is not, well, general enough).

Source Link
WReach
  • 69.3k
  • 4
  • 165
  • 272

Mathematica 10.1 almost supports this operation directly:

assoc // Query[Transpose]

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)

All that remains is to delete the unwanted Missing elements:

assoc // Query[Transpose] // DeleteCases[#, _Missing, {2}] &

(*
<| "a" -> <|"1" -> "x"|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>, 
   "c" -> <|"2" -> "k"|>
|>
*)

We can see that Query uses the undocumented function GeneralUtilities`AssociationTranspose to do the heavy-lifting:

Query[Transpose] // Normal

(* GeneralUtilities`AssociationTranspose *)

assoc // GeneralUtilities`AssociationTranspose

(*
<| "a" -> <|"1" -> "x", "2" -> Missing["KeyAbsent", "a"]|>,
   "b" -> <|"1" -> "y", "2" -> "z"|>,
   "c" -> <|"1" -> Missing["KeyAbsent", "c"], "2" -> "k"|>
|>
*)