如何创建通用JSON解析代码?

时间:2014-10-03 13:53:00

标签: json parsing elixir

所以我通过使用jsx解析一些json来解析返回的列表。我通过搜索具有特定名称的元组来提取一些选定的值,如下所示:

defp get_link([{"link",_link} | _t]), do: _link
defp get_link([_h | _t]), do: get_link(_t)
defp get_link([]), do: ""

我正在为我要提取的几个单独的元素做同样的事情,当我看到许多代码只在一个参数上有所不同时,我闻到了一个糟糕的代码味道。我的意思是这样的代码:

defp get_link([{"link",_link} | _t]), do: _link
defp get_link([_h | _t]), do: get_link(_t)
defp get_link([]), do: ""

defp get_last_updated([{"last updated",_last_updated | _t]), do: _last_updated
defp get_last_updated([_h | _t]), do: get_last_updated(_t)
defp get_last_updated([]), do: ""

defp get_creator([{"creator",_creator} | _t]), do: _creator
defp get_creator([_h | _t]), do: get_creator(_t)
defp get_creator([]), do: ""
对我来说,违反DRY原则的气味。

所以我想我可能会做这样的事情:

defp get_json_element([{element_to_get,value_of_element} | _t]), do: _value_of_element
defp get_json_element([_h | _t]), do: get_json_element(_t)
defp get_json_element([]), do: ""

但是假设它可以工作(它编译但是我不确定它会做我想要的),我该怎么称呼它?我无法拨打get_json_element(["link", _link])(或者至少我认为我不能)我的意思是通常我会将jsx.decode返回的列表传递给各种get_X函数但是后来如何传递模式匹配表达式?对不起 - 我不认为我已经很好地表达了我的问题,但我无法弄清楚如何更好地表达它。

这是否应该使用宏来减少重复代码?如果是这样,有没有人写过这种宏?

还想知道是否有更好的方法来表示空字符串。使用""对我来说,这似乎不是最好的方法。还是有其他价值我可以回来?也许返回nil?

1 个答案:

答案 0 :(得分:2)

你绝对可以使用宏

您可以使用https://github.com/Licenser/jsxd库来操作jsx

返回的数据结构

您可以使用像

这样的通用函数
def get(json, key, default \\ nil) do                                                                            
  case List.keyfind(json, key, 0, default) do
    {^key, value} -> value
    ^default -> default
  end 
end 

您的解决方案

defp get_json_element([{element_to_get,value_of_element} | _t]), do: _value_of_element
defp get_json_element([_h | _t]), do: get_json_element(_t)
defp get_json_element([]), do: ""

无效,因为{element_to_get, value_of_element}会匹配任何具有相同形状的元组{_, _}