`map`基于条件

时间:2013-03-16 00:22:28

标签: ruby struct

我有这样的结构:

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...
]

如果我想获取所有设备的IP地址,我可以使用test_clients.map(&:ip)。如何选择特定设备的IP地址,例如所有称为"tablet"的设备类型?我怎么能用map

来做到这一点

4 个答案:

答案 0 :(得分:21)

首先select

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

答案 1 :(得分:7)

答案很简单:

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

使用条件进行映射会为条件失败的客户端提供nils,因为只有我们保留compact,这实际上会刷新nil值。

答案 2 :(得分:0)

使用#collect的Sergio Tulentsev方法的替代方法。我认为在这里使用#collect在语义上是正确的。我知道O.P.询问如何使用#map,但这是我的两分钱。

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)

答案 3 :(得分:0)

Ruby 2.7 +

Ruby 2.7为此引入了filter_map。它是惯用语言和高性能,我希望它很快会成为常态。

例如:

numbers = [1, 2, 5, 8, 10, 13]
enum.filter_map { |i| i * 2 if i.even? }
# => [4, 16, 20]

这里是good read on the subject

希望对某人有用!