9

I apologise in advance if this is a duplicate. I have looked at this question, yet have been unable to figure out how to use it when it's not nested: Link. I have a grouped list of random words

    list = <|"Net1" -> {{"counteroffensive", "nonpayment", 
     "dieresis"}, {"suffragan", "identifiably"}}, 
  "Net2" -> {{"psychiatrist", "pusher", "generous", "praising", 
     "thy"}, {"amplification", "amylase", "shooting", "tumbler", 
     "mimosa", "dengue"}}|>

And the output should be:

    output = {
<|"Net1" -> {"counteroffensive", "nonpayment", 
     "dieresis"}|>, 
<|"Net1" -> {"suffragan", 
     "identifiably"}|>, 
<|"Net2" -> {"psychiatrist", "pusher", 
     "generous", "praising", "thy"}|>, 
<|"Net2" -> {"amplification", 
     "amylase", "shooting", "tumbler", "mimosa", "dengue"}|>}

Much appreciated for your help

Tim B
  • 547
  • 2
  • 9

6 Answers6

7
KeyValueMap[Thread[#1 -> #2] &, list] // Flatten // Map[Association]
Rohit Namjoshi
  • 10,212
  • 6
  • 16
  • 67
4
Association /@ Flatten[Table[Thread[key -> list[key]], {key, Keys[list]}], 1]
Chris
  • 1,076
  • 5
  • 9
4

Using ideas from this answer by Leonid:

unMerge = Catenate @* MapIndexed[Association /@ Thread[#2[[1, 1]] -> #] &];

unmerged = unMerge @ list

{<|"Net1" -> {"counteroffensive", "nonpayment", "dieresis"}|>,
<|"Net1" -> {"suffragan", "identifiably"}|>,
<|"Net2" -> {"psychiatrist", "pusher", "generous", "praising", "thy"}|>,
<|"Net2" -> {"amplification", "amylase", "shooting", "tumbler", "mimosa", "dengue"}|>}

Merge[Identity] @ unmerged  == list

True

Another way to use MapIndexed:

unMerge2 = Map[Association] @* Catenate @* MapIndexed[Thread[#2[[1, 1]] -> #] &];

unMerge @ list == unMerge2 @ list

True

Also:

unMerge3 = Query[Catenate @* Map[KeyValueMap[Association @* Rule]] @* Transpose];

Sort @ unMerge @ list == Sort @ unMerge3 @ list

True

If the output from GeneralUtilities`AssociationTranspose is acceptable, you can also use:

Query[Transpose] @ list

{<|"Net1" -> {"counteroffensive", "nonpayment", "dieresis"}, "Net2" -> {"psychiatrist", "pusher", "generous", "praising", "thy"}|>,
<|"Net1" -> {"suffragan", "identifiably"}, "Net2" -> {"amplification", "amylase", "shooting", "tumbler", "mimosa", "dengue"}|>}

kglr
  • 394,356
  • 18
  • 477
  • 896
4

You can use AssociationTranspose,

Needs["GeneralUtilities`"]
AssociationTranspose[list]
(* 
    {
        <|
            "Net1" -> {"counteroffensive", "nonpayment", "dieresis"},
            "Net2" -> {"psychiatrist", "pusher", "generous", "praising", "thy"}
        |>,
        <|
            "Net1" -> {"suffragan", "identifiably"},
            "Net2" -> {"amplification", "amylase", "shooting", "tumbler", "mimosa", "dengue"}
        |>
    }
*)

which is very close to the output desired in the OP.

Jason B.
  • 68,381
  • 3
  • 139
  • 286
3

Shortest yet?

<|#|> & /@ Join @@ Thread /@ Normal[list]
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
2

If you don't care about key order, transposing a Dataset gives you what you want, it just needs a catenation of association rules and transforming it back to list with Normal:

Dataset[list][Transpose /* Normal /* Catenate] // Normal
swish
  • 7,881
  • 26
  • 48