`map`基于条件

syl*_*ian 11 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...
]
Run Code Online (Sandbox Code Playgroud)

如果我想获得所有设备的IP地址,我可以使用test_clients.map(&:ip).如何选择特定设备的IP地址,比如所谓的所有设备类型"tablet"?我怎么能这样做map

Ser*_*sev 22

select第一

clients.select{|c| c.type == 'tablet'}.map(&:ip)
Run Code Online (Sandbox Code Playgroud)


Sk.*_*fan 8

答案很简单:

clients.map { |client| client.ip if client.type == 'tablet' }.compact
Run Code Online (Sandbox Code Playgroud)

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

  • “compact” 还会迭代数组并检查每个值是否为“nil”。塞尔吉奥的回答实际上可以更快。在您的示例中,两次迭代都超过了“clients”的整个长度,而在 Sergio 的示例中,第二次迭代可能超过了较小的集合。 (3认同)

SRa*_*ack 7

红宝石 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]
Run Code Online (Sandbox Code Playgroud)

这是有关该主题好读物

希望这对某人有用!