Here it is in Erlang, which is another language which forces you not to think in loops:
csv_to_maps([Head | Lines]) ->
lists:map(fun(L) -> maps:from_list(lists:zip(Head), L)) end, Lines).
Another language which works differently is Rebol: csv-to-maps: func [csv-data] [
map-each line next csv-data [map zipmap first csv-data line]
]
Whats interesting about above is that `first csv-data` will be re-evaluating on each `map-each` sequence. Of course you can assign to variable beforehand. Alternatively because code-is-data and vice-versa you can use COMPOSE it inline: csv-to-maps: func [csv-data] [
map-each line next csv-data compose [map zipmap (first csv-data) line]
]
:)NB. Rebol doesn't come with ZIPMAP so here's a definition for above to work:
zipmap: func [keys vals] [
collect [
forall keys [
keep reduce [keys/1 vals/(index? keys)]
]
]
]