2017-11-17 14 views
4

Posion.decode를 사용하여 다음 JSON을 구문 분석했습니다!Elixir의 JSON 값 매핑

json = %{"color-Black|size:10" => 
    %{"attributes" => %{"color" => "Black","size" => "11"},  
     "isAvailable" => true,  
    "pricing" => %{"standard" => "$415.00", "sale" => 415}}, 
"color|size-EU:9.5" => 
    %{"attributes" => %{"color" => "Black","size" => "11"},  
     "isAvailable" => true,  
    "pricing" => %{"standard" => "$415.00", "sale" => 415}}} 

나는이를 매핑 할 내가 노드 요소가 변경의 텍스트로 JSON 요소를 얻을 수 없습니다입니다. 지금까지 시도했습니다.

Enum.map(json , fn(item) -> 
%{ 
    color: item.attributes["color"],     
    size: item.attributes["size"], 
    price: item.pricing["standard"] * 100, 
    isAvailable: item.isAvailable 
} 
end) 

그러나이 코드는 액세스와 관련된 몇 가지 오류를 제공합니다.

답변

2

세 가지 : 당신은지도를 가지고

  1. 그래서 Enum.map 당신에게 키와 값의 튜플을 줄 것이다. 당신은 여기에 값을 원하는 이렇게 :지도에서

    fn {_, item} -> 
    
  2. 키는 문자열입니다. 도트 구문은 원자 키에만 적용됩니다.

    item["attributes"] 
    

    대신 다른 키에 대한

    item.attributes 
    

    과 유사한의 : 당신은 할 필요가있다.

  3. 보유하고있는 가격은 문자열입니다. 곱하기 전에 Float로 변환해야합니다. 당신은 String.trim_leadingString.to_float를 사용하여 이런 식으로 작업을 수행 할 수 있습니다

    iex(1)> "$123.45" |> String.trim_leading("$") |> String.to_float 
    123.45 
    

Enum.map(json, fn {_, item} -> 
    %{ 
    color: item["attributes"]["color"], 
    size: item["attributes"]["size"], 
    price: item["pricing"]["standard"] |> String.trim_leading("$") |> String.to_float |> Kernel.*(100), 
    isAvailable: item["isAvailable"] 
    } 
end) 
|> IO.inspect 

출력 :지도를 매핑하는 동안

[%{color: "Black", isAvailable: true, price: 4.15e4, size: "11"}, 
%{color: "Black", isAvailable: true, price: 4.15e4, size: "11"}] 
4

의 반복 키 - 값 쌍은 올 튜플로 매퍼 {key, value} :

Enum.map(json, fn {_, %{"attributes" => attributes, 
         "isAvailable" => isAvailable, 
         "pricing" => pricing}} -> 
    %{ 
    color: attributes["color"], 
    size: attributes["size"], 
    price: pricing["standard"], 
    isAvailable: isAvailable 
    } 
end) 

#⇒ [ 
# %{color: "Black", isAvailable: true, price: "$415.00", size: "11"}, 
# %{color: "Black", isAvailable: true, price: "$415.00", size: "11"} 
# ] 

5,여기 우리 정합 자체의 코드를 단순화하기 위해 매퍼 값 일치 인플레 이스 패턴을 사용하는 것이 덜 오류가 발생하기 쉬운 나쁜 입력하는 경우이다.

0

property이 원자이고 json 맵에서 키가 문자열 인 경우에만 thing.property 구문을 사용할 수 있기 때문에 액세스 오류가 발생합니다.

더 쉽게 만들 수있는 한 가지는 Poison.decode은 두 번째 인수 인 keys: :atoms을 사용하여 아톰 키가있는지도를 반환 할 수 있다는 것입니다. 여기에있는 것을 사용하면 문제가 해결됩니다.

json_atoms = Poison.encode!(json) |> Poison.decode!(keys: :atoms) 
convert_price = fn x -> 
    String.trim_leading(x, "$") 
    |> String.to_float 
    |> &(&1 * 100) 
    |> trunc 
end 

Enum.map(json_atoms, fn {_k,v} -> %{ 
    color: v.attributes.color, 
    size: v.attributes.size, 
    price: convert_price.(v.pricing.standard), 
    isAvailable: v.isAvailable 
} end)