2015-03-30 15 views
9

, bir yapıElixir için bir yapıda nil değerini bırakmak için iyi bir çözüm nedir? Örneğin

post = %Post{title: "Title", desc: nil} 

var Ve ben

%{title: "Title"} 

Çözümümün almak istiyorum

post 
    |> Map.delete(:__struct__) # change the struct to a Map 
    |> Enum.filter(fn {_, v} -> v end) 
    |> Enum.into(%{}) 

Çalışıyor gibi ama daha iyi bir tane var?

Güncelleme:

Ben can sıkıcı dönüştürme Struct sonra Numaralandırma, sonra tekrar Map, Map ila hissediyorum. Özlü bir yolu var mı? Bunun yerine

post 
    |> Map.delete(:__struct__) # change the struct to a Map 
    |> Enum.filter(fn {_, v} -> v end) 
    |> Enum.into(%{}) 

yapmanın

+1

Değil - nasıl daha iyi? Değiştireceğim bir şey, "Map.delete (...)" Map.delete (...) " –

+0

yerine" Map.from_struct "kullanıyor. Teşekkürler, Yapımdan Haritaya, sonra Enum'a, sonra Harita'ya dönüşümü rahatsız ediyor. Özlü bir yolu var mı? –

+1

@Tony çözümünüzün tamam olduğunu düşünüyorum, ama bir kusuru vardır: Ayrıca, değerin "yanlış" olduğu girdileri de atar. Filtrelemeyi "Enum.filter (fn {_, v} -> v! = Nil end) veya" Enum.reject (fn {_, v} -> v == nil son) " –

cevap

16

Sen Sadece biraz daha temiz elle __struct__ anahtarını silerek daha var

post 
    |> Map.from_struct 
    |> Enum.filter(fn {_, v} -> v != nil end) 
    |> Enum.into(%{}) 

yapabilirsiniz.

+2

İkinci örnekteki filtrelemeyi ya 'v! = Nil' olarak değiştirmelisiniz ya da 'filtre' yerine 'reddet'i kullanmalısınız. –

+0

Güzel yakalama. Mantık hatası. – hahuang65

+0

Btw, StackOverflow, kod bloklarını biçimlendirmek için dört boşluk girintisi kullanır, backticks yalnızca satır içi kod içindir. Cevabınızı düzenlediniz. –

9

Ayrıca comprehensions ile yapabilirsiniz:

for {k, v} <- Map.from_struct(post), v != nil, into: %{}, do: {k, v} 
+1

İlham verdiğiniz cevabınız için teşekkür ederiz! –

1

Ayrıca, bu gibi yazılabilir:

ne istediğini çok açık
post 
    |> Map.from_struct 
    |> Enum.reject(fn {_, v} -> is_nil(v) end) 
    |> Map.new 
İlgili konular