2013-03-16 32 views
5

Mam struct tak:`map` na podstawie stanu

Struct.new("Test", :loc, :type, :hostname, :ip) 

clients = [ 
Struct::TestClient.new(1, :pc, "pc1", "192.168.0.1") 
Struct::TestClient.new(1, :pc, "pc2", "192.168.0.2") 
Struct::TestClient.new(1, :tablet, "tablet1", "192.168.0.3") 
Struct::TestClient.new(1, :tablet, "tablet2", "192.168.0.3") 
and etc... 
] 

Jeśli chcę uzyskać adres IP wszystkich urządzeń, które można używać test_clients.map(&:ip). Jak wybrać adresy IP konkretnych urządzeń, na przykład wszystkie typy urządzeń o nazwie "tablet"? Jak mogę to zrobić z map?

Odpowiedz

10

Wykonaj select pierwszy

clients.select{|c| c.type == 'tablet'}.map(&:ip) 
-1

zastępcę metody Sergio Tulentsev Korzystanie #collect. Myślę, że używanie tutaj #collect jest semantycznie poprawne. Wiem, że O.P. zapytał, jak używać #map, ale to moje dwa centy.

clients.collect { |c| c.ip if c.type == "tablet" } # will return nils for clients where the type is not "tablet" 

# or 

clients.select { |c| c.type == "tablet" }.collect(&ip) 
+0

Przepraszam za duplikowanie odpowiedzi, zbyt wiele razy uderz w klawisz Backspace i wróć do tworzenia, a nie edycji. – silasjmatson

+0

Jestem ciekawa, jak odróżnić różnicę między 'collect' i' map'? Czy też 'collect (& ip)' zwraca to, czego oczekujesz? –

+0

Zwykle używam 'collect', gdy tylko pobieram wartości z zestawu obiektów, i' map' gdy robię pęczek logiki w bloku lub zwracam tablicę, która zmieniła wartości. Czy jestem w tym zły? – silasjmatson

0

Odpowiedź jest tak prosta, jak:

clients.map { |client| client.ip if client.type == 'tablet' }.compact 

Mapowanie warunku da Nils dla klientów, które jednak nie warunek, na który tylko my zachowaliśmy compact, które będą faktycznie przepłukać wartości zerowe.

+1

Nie ma potrzeby używania, 'select' i' map', jak wspomniano w odpowiedzi Sergio Tulentseva, ponieważ spowoduje to dwie pętle i stosunkowo wolniej. –

Powiązane problemy