15

我有一个这样的结构:

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

4 回答 4

28

先做select一个

clients.select{|c| c.type == 'tablet'}.map(&:ip)
于 2013-03-16T00:25:26.220 回答
13

红宝石 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]

这是一个很好的阅读主题

希望这对某人有用!

于 2019-06-12T15:14:38.757 回答
11

答案就这么简单:

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

使用条件映射将为未满足条件的客户端提供 nil,因为只有我们保留了compact,这实际上会刷新 nil 值。

于 2017-07-12T20:21:02.020 回答
2

Sergio Tulentsev 使用#collect. 我认为 using#collect在语义上是正确的。我知道 OP 询问如何使用#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)
于 2013-03-16T00:42:53.217 回答