How can I create an Association from a multidimensional list of values and a list of keys?

Clear[helper];
helper[tl_] := GroupBy[tl, First -> Rest, helper];
helper[{{n_}}] := n;
helper@Transpose@Append[Flatten@vals]@Transpose@Tuples[dims]

The idea is to build a list of paths to each leaf, then use a recursive GroupBy build the association tree from the list.

Update

I have managed to come up with something faster. But the code becomes more ugly.

Clear[fvals, i, maketree];
fvals = Flatten[vals, Depth[vals] - 3];
maketree[{first_, rest__}] := 
  AssociationThread[first -> Table[maketree[{rest}], Length@first]];
maketree[{first_}] := AssociationThread[first, fvals[[i++]]];

i = 1; maketree[dims]
(*<|"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|>|>|>|>*)

I made some timing experiments on code available. (1000 times, repeated timing).

My previous: 0.0665s

My current: 0.019s

Kuba: 0.0400s

andre: 0.0299s

Anton: 0.307s


Assuming vals has depth corresponding to dims length:

Module[{i = -2}
, Fold[
    Function[{val, dim}, Map[AssociationThread[dim -> #] &, val, {i--}]]
  , vals
  , Reverse @ dims
  ]
]
<|"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|>|>|>|>

Here is a basic approach without explicit recursion :

vals = {{{{0., 633.25}, {642.96, 677.34}}, {{591.56, 632.45}, {634.9, 
         715.6}}}}
dims = {{"New York City"}, {"Terrace house", "Apartment"},
          {"Two bed", "Three bed"}, {"2016", "2017"}}

MapIndexed[dims[[Length[#2],Last[#2]]]->#1&,vals,{1,-1}] /. x:{_Rule ...} :> Association[x]