2017-07-23 75 views
2

我有,我想用下面的格式解析文件到嵌套dictonary

[key_1] 
inner_key_1 inner_entry_1 
inner_key_2 inner_entry_2 
inner_key_3 inner_entry_3 
inner_key_4 inner_entry_4 
[key_2] 
inner_key_5 inner_entry_5 
inner_key_6 inner_entry_6 
inner_key_7 inner_entry_7 
inner_key_8 inner_entry_8 

那麼這將被映射到嵌套藥劑字典像這樣讀取配置文件。

%{key_1 => %{inner_key_1 => inner_entry_1, ... }, key_2 => %{inner_key_5 => inner_entry_5,...}} 

我很難概念化如何使用Elixir和函數式編程來做到這一點。我曾嘗試使用Stream庫來實現此目的,但沒有運氣。

回答

5

一個簡單的解決方案可能類似於此:

def read_config(file) do 
    file 
    |> File.stream!() 
    |> Stream.map(&String.trim/1) 
    |> Enum.reduce({%{}, nil}, &read_config/2) 
    |> elem(0) 
end 

defp read_config("[" <> key, {acc, _top_key}) do 
    key = String.trim_trailing(key, "]") 
    {Map.put(acc, key, %{}), key} 
end 
defp read_config(key_value, {acc, top_key}) do 
    [key, value] = String.split(key_value, " ") 
    {put_in(acc, [top_key, key], value), top_key} 
end 

當翻譯勢在必行環路成實用的風格,你最經常使用減少。下一步是在每次迭代過程中確定所需的所有狀態 - 在這種情況下,我們需要「到目前爲止的結果」和當前的頂級密鑰 - 這與您在命令式解決方案中使用的類似循環外的可變變量。

+0

爲什麼類似''[「<> key <>」]「'不允許,那麼禁止使用'<>'運算符的原因是什麼? – cogle

+1

只有二進制匹配的最後部分可以忽略大小。 ''foo「<> bar'語法與'<<」foo「,bar :: binary >>'相同,所以這個限制在這裏也適用。從某種意義上說,它只是當前實現的一個限制,可以通過Erlang本身的一些工作來解決。 – michalmuskala