2017-10-09 48 views
0

我试图在嵌套的JSON响应中查找URL并映射它们。我的功能到目前为止是这样的:Elixir:通过嵌套JSON中的值前缀查找

def list(env, id) do 
    Service.get_document(env, id) 
    |> Poison.decode! 
    |> Enum.find(fn {_key, val} -> String.starts_with?(val, 'https') end) 
end 

的JSON看起来大致是这样的:

"stacks": [ 
    { 
     "boxes": [ 
     { 
      "content": "https://ddd.cloudfront.net/photos/uploaded_images/000/001/610/original/1449447147677.jpg?1505956120", 
      "box": "photo" 
     } 
     ] 
    } 
    ], 
    "logo": "https://ddd.cloudfront.net/users/cmyk_banners/000/000/002/original/banner_CMYK.jpg?1397201875" 

所以URL可以有任意键,并且在任何级别。

与该代码我得到这个错误:

no function clause matching in String.starts_with?/2 

任何人有一个更好的方式,JSON响应找?

回答

3

你将不得不使用这个递归函数,它处理三种类型的数据:

  1. 在地图,它递归在其所有值。
  2. 对于列表,它遍历所有元素。
  3. 对于字符串,它选择以 “https”

这里有一个简单的实现,它接受一个术语和一个字符串检查与starts_with?开头的字符串:

defmodule A do 
    def recursive_starts_with(thing, start, acc \\ []) 

    def recursive_starts_with(binary, start, acc) when is_binary(binary) do 
    if String.starts_with?(binary, start) do 
     [binary | acc] 
    else 
     acc 
    end 
    end 
    def recursive_starts_with(map, start, acc) when is_map(map) do 
    Enum.reduce(map, acc, fn {_, v}, acc -> A.recursive_starts_with(v, start, acc) end) 
    end 
    def recursive_starts_with(list, start, acc) when is_list(list) do 
    Enum.reduce(list, acc, fn v, acc -> A.recursive_starts_with(v, start, acc) end) 
    end 
end 

data = %{ 
    "stacks" => [ 
    %{ 
     "boxes" => [ 
     %{ 
      "content" => "https://ddd.cloudfront.net/photos/uploaded_images/000/001/610/original/1449447147677.jpg?1505956120", 
      "box" => "photo" 
     } 
     ] 
    } 
    ], 
    "logo" => "https://ddd.cloudfront.net/users/cmyk_banners/000/000/002/original/banner_CMYK.jpg?1397201875" 
} 

data |> A.recursive_starts_with("https") |> IO.inspect 

输出:

["https://ddd.cloudfront.net/photos/uploaded_images/000/001/610/original/1449447147677.jpg?1505956120", 
"https://ddd.cloudfront.net/users/cmyk_banners/000/000/002/original/banner_CMYK.jpg?1397201875"] 
+0

这是_brilliant_,对于大量的帮助来说非常重要。再次。 –