Given a list of values such as
vals = {{{{0., 633.25}, {642.96, 677.34}}, {{591.56, 632.45}, {634.9, 715.6}}}}
and a list of "Dimensions" such as
dims = {{"New York City"}, {"Terrace house", "Apartment"}, {"Two bed", "Three bed"}, {"2016", "2017"}}
how can I create the Association (I suppose really a tree)
<|"New York City" ->
<|"Terrace House" ->
<|"Two Bed" ->
<|"2016" -> 0.,
"2017" -> 633.25|>,
"Three Bed" ->
<|"2016" -> 642.96,
"2017" -> 677.34|>|>,
"Apartment" ->
<|"Two Bed" ->
<|"2016" -> 591.56,
"2017" -> 632.45|>,
"Three Bed" ->
<|"2016" -> 634.9,
"2017" -> 715.6|>|>|>|>
You can see that each level in vals
is a level in the tree - the innermost level is dims[[4]]
(2016 or 2017), the next level up is dims[[3]]
(two bed or three bed), next is dims[[2]]
(terraced house or apartment), and finally the topmost level is dims[[1]]
, New York City.
I have attempted a few different approaches here, but I think my understanding of how Levels work is lacking here.
My best attempt so far is the following:
Table[
MapIndexed[
dims[[lvl, Last[#2]]] -> # &, vals, {lvl}],
{lvl, Length@Dimensions[vals]}]
The output from this is:
{{"New York City" -> {{{0., 633.25}, {642.96, 677.34}}, {{591.56, 632.45}, {634.9, 715.6}}}},
{{"Terrace house" -> {{0., 633.25}, {642.96, 677.34}},
"Apartment" -> {{591.56, 632.45}, {634.9, 715.6}}}},
{{{"Two bed" -> {0., 633.25},
"Three bed" -> {642.96, 677.34}},
{"Two bed" -> {591.56, 632.45},
"Three bed" -> {634.9, 715.6}}}},
{{{{"2016" -> 0., "2017" -> 633.25},
{"2016" -> 642.96, "2017" -> 677.34}},
{{"2016" -> 591.56, "2017" -> 632.45},
{"2016" -> 634.9, "2017" -> 715.6}}}}}
Which is sort of close, but not correct.
My solution would ideally scale to dimensions and values of any size - not just one or two dimensional data (another city, for instance, or a hundred years, or both, and also more house sizes, and so on).
I'm sure the correct answer here is a recursive function, and I'm sure it's not even that hard, I'm just not thinking about it correctly!
Thanks for your help.
Edit:
I have done a little more exploration and have gotten a little bit closer using Nest.
Module[{i = 0, d = Reverse[dims]},
Nest[(i++;
Partition[
Riffle[#, d[[i]], {1, -2, 2}],
Length[d[[i]]]]) &,
Flatten[vals], 3]]
This gives me
{{"Terrace house", {"Two bed", {"2016", 0.}}},
{"Apartment", {"Three bed", {"2017", 633.25}}},
{"Terrace house", {"Two bed", {"2016", 642.96}}},
{"Apartment", {"Three bed", {"2017", 677.34}}},
{"Terrace house", {"Two bed", {"2016", 591.56}}},
{"Apartment", {"Three bed", {"2017", 632.45}}},
{"Terrace house", {"Two bed", {"2016", 634.9}}},
{"Apartment", {"Three bed", {"2017", 715.6}}}}
This is getting pretty close! However, applying it an extra time (changing 3 to 4 in the Nest) gives me the following:
{{"New York City"}, {{"Terrace house", {"Two bed", {"2016", 0.}}},
{"New York City"}, {{"Apartment", {"Three bed", {"2017", 633.25}}}},
{"New York City"}, {{"Terrace house", {"Two bed", {"2016", 642.96}}}},
{"New York City"}, {{"Apartment", {"Three bed", {"2017", 677.34}}}},
{"New York City"}, {{"Terrace house", {"Two bed", {"2016", 591.56}}}},
{"New York City"}, {{"Apartment", {"Three bed", {"2017", 632.45}}}},
{"New York City"}, {{"Terrace house", {"Two bed", {"2016", 634.9}}}},
{"New York City"}, {{"Apartment", {"Three bed", {"2017", 715.6}}}}}
Close, but not right, yet.