2017-02-02 15 views
1

私は地図をエリクシルで使用しています。異なるフォーマットの地図を比較する - elixir

は、いくつかは%{"foo": "bar"}形式で

であり、一部には、私は2つのマップ持っ%{"foo" => "bar"}

にあります

a = %{"foo": "bar"} 
b = %{"foo" => "bar"} 

どのように私はこれらの二つのマップを比較することができますか?

Map.equal?(a, b) 

戻りfalse

+0

これはおそらくこれです:http://learningwithjb.com/posts/the-many-different-ways-to-key-elixir-maps – dina

答えて

2

あなたが持っているマップは、異なる形式ではありません。彼らは異なるキーを持っています。最初の("foo":)を使用して

iex(1)> Map.equal? %{"foo": 4}, %{:"foo" => 4} 
true 

は現在Map.equal?/2関数はキーと値が同じであることを確認するに見えます

秒(:"foo" =>)を書くためだけの短い手です。

エリクシル:"foo"は原子であり、"foo"はバイナリ(時には文字列と呼ばれる)です。

iex(1)> is_atom :"foo" 
true 
iex(2)> is_binary :"foo" 
false 
iex(3)> is_atom "foo" 
false 
iex(4)> is_binary "foo" 
true 

これは、これらの2つの値が同じではないため、Map.equal?/2が失敗する理由です。

しかし、型が違うことに気をつけず、型の "内容"について気にするならば、すべてのキー(と多分値)を文字列に変換して比較することができます。

for {key, value} <- my_map do 
    {inspect(key), inspect(value)} 
end 

は、上記のコードは考慮ネストされたマップに入れていないと、やみくもまたはあなたが何をしたいのかであってもなくてもよいの文字列に変換されますのでご注意ください。

残念ながら、これは両方のマップを複数回トラバースする必要があることを意味します。一度各マップを変換し、再びそれらが等しいかどうかをテストします。いずれかのマップがかなり大きい場合、これには長い時間がかかることがあります。

Map.equal?/2の仕組みに従うことが好ましい。キーのタイプが異なる場合は、同じであってはなりません。あなたが本当に必要な場合は、あなた自身で変換を行うことができます。

+1

私は考える価値があると思います: '' foo ==: "foo" '、引用符はいくつかの非標準文字を扱うためのものです。 – nietaki

+0

はい。ありがとう@nietaki。非標準文字の例はスペースです。空白を持つものを引用符なしでアトムとして表現することはできません。 –

関連する問題