Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 长生不老药:如何计算字符串中列表项的数量_Elixir_Elixir Poison - Fatal编程技术网

Elixir 长生不老药:如何计算字符串中列表项的数量

Elixir 长生不老药:如何计算字符串中列表项的数量,elixir,elixir-poison,Elixir,Elixir Poison,我正在尝试使用毒药解码以下json字符串 iex(1)> fetch(1) {:ok, "{\"name\":\"Anabela\",\"surname\":\"Neagu\",\"gender\":\"female\",\"region\":\"Romania\"}"} iex(2)> fetch(2) {:ok, "[{\"name\":\"Juana\",\"surname\":\"Su├írez\",\"gender\":\"female\",\"region\":\"A

我正在尝试使用毒药解码以下json字符串

iex(1)> fetch(1)
{:ok,
 "{\"name\":\"Anabela\",\"surname\":\"Neagu\",\"gender\":\"female\",\"region\":\"Romania\"}"}
iex(2)> fetch(2)
{:ok,
 "[{\"name\":\"Juana\",\"surname\":\"Su├írez\",\"gender\":\"female\",\"region\":\"Argentina\"},{\"name\":\"ðíðÁÐÇð│ðÁð╣\",\"surname\":\"ðƒð╗ð¥Ðéð¢ð©ð║ð¥ð▓\",\"gender\":\"male\",\"region\":\"Russia\"}]"}
执行
fetch(1)|>decode_响应
将不起作用,尽管它是为param严格支持1

我确实有以下错误

10:07:52.663 [error] GenServer Newsequence.Server terminating
** (BadMapError) expected a map, got: {"gender", "female"}
    (stdlib) :maps.find("gender", {"gender", "female"})
    (elixir) lib/map.ex:145: Map.get/3
    lib/poison/decoder.ex:49: anonymous fn/3 in Poison.Decode.transform_struct/4
    (stdlib) lists.erl:1262: :lists.foldl/3
    lib/poison/decoder.ex:48: Poison.Decode.transform_struct/4
    lib/poison/decoder.ex:24: anonymous fn/5 in Poison.Decode.transform/4
    (stdlib) lists.erl:1262: :lists.foldl/3
    lib/poison/decoder.ex:24: Poison.Decode.transform/4 Last message: {:getpeople, 1} State: {[], #PID<0.144.0>}
然后我认为param等于1,函数应该是

   def decode_response({:ok, body}) do
        Poison.decode!(body, as: %Personne{})
    end
最后,我认为在fetch函数给出的字符串中计算元组并使用一个保护来选择使用哪个decode_响应是一个好主意,但我不知道如何使用

有人能给我指一下正确的方向吗

问候,


pierre

您可以先使用
Poison.decode对本地地图/列表进行解码/1
,然后将
的相关值计算为:
,最后使用本机数据结构和要解码的结构调用
毒药.decode/2

def decode_response({:ok, body}) do
  parsed = Poison.decode!(body)
  as =
    cond do
      is_map(parsed) -> %Personne{}
      is_list(parsed) -> [%Personne{}]
    end
  Poison.Decoder.decode(parsed, as: as)
end
演示:

输出:

%{"gender" => "female", "name" => "Anabela", "region" => "Romania",
  "surname" => "Neagu"}
[%{"gender" => "female", "name" => "Juana", "region" => "Argentina",
   "surname" => "Suárez"},
 %{"gender" => "male", "name" => "ðíðÁÐÇð│ðÁð╣",
   "region" => "Russia",
   "surname" => "ðƒð╗ð¥Ðéð¢ð©ð║ð¥ð▓"}]

这有点幼稚,但可以省去对JSON进行第二次解析:

if (body |> String.trim_leading() |> String.starts_with?("[")) do
  Poison.decode!(body, as: [%Personne{}])                    
else                                                       
  Poison.decode!(body, as: %Personne{})                      
end
注意,如果您使用的是Elixir 1.2或更低版本,那么您将希望使用
String.lstrip/1
而不是
String.trim\u leading/1

另一种方法是将其解码为映射,使用转换键,然后使用转换为结构

  def decode_response({:ok, body}) do
    body |> Poison.decode!() |> string_map_struct(Personne)
  end

  defp string_map_struct(entry, module) do
    params =
      entry
      |> Enum.map(fn {key, val} ->
        key = to_existing_atom(key)
        {key, val}
      end)
      |> Enum.into(%{})
    struct(module, params)
  end

  defp to_existing_atom(key) do
    try do
      String.to_existing_atom(key)
    rescue
      ArgumentError -> key
    end
  end

我想找一个更简单的方法(比如下面的Dogbert解),但我会仔细看看你的。看起来真的很有趣。
if (body |> String.trim_leading() |> String.starts_with?("[")) do
  Poison.decode!(body, as: [%Personne{}])                    
else                                                       
  Poison.decode!(body, as: %Personne{})                      
end
  def decode_response({:ok, body}) do
    body |> Poison.decode!() |> string_map_struct(Personne)
  end

  defp string_map_struct(entry, module) do
    params =
      entry
      |> Enum.map(fn {key, val} ->
        key = to_existing_atom(key)
        {key, val}
      end)
      |> Enum.into(%{})
    struct(module, params)
  end

  defp to_existing_atom(key) do
    try do
      String.to_existing_atom(key)
    rescue
      ArgumentError -> key
    end
  end