考虑以下
users.collect do |user|
user.favorite_song.presence
end.compact.first
在这种情况下,我想要在我的用户中遇到的第一首最喜欢的歌曲。
这可以写得更好吗?
我试过了
users.find do |user|
user.favorite_song.presence
end
但它会返回第一个用户最喜欢的歌曲,而不是最喜欢的歌曲本身。
考虑以下
users.collect do |user|
user.favorite_song.presence
end.compact.first
在这种情况下,我想要在我的用户中遇到的第一首最喜欢的歌曲。
这可以写得更好吗?
我试过了
users.find do |user|
user.favorite_song.presence
end
但它会返回第一个用户最喜欢的歌曲,而不是最喜欢的歌曲本身。
如果users
数组不是太大,你的第一个解决方案很好,可以像这样重写:
users.map(&:favorite_song).compact.first
您还可以按如下方式修改第二种方法:
users.find { |user| user.favorite_song.present? }.favorite_song
这两种解决方案都假设某个用户中存在 a favorite_song
,如果不存在则会引发异常。try
您可以使用(仅限 Rails)优雅地避免这种情况:
users.find { |user| user.favorite_song.present? }.try(:favorite_song)
关于什么:
users.each do |user|
break user.favorite_song if user.favorite_song.present?
end
user.favorite_song
如果条件为将返回,true
否则将返回users
favorite_song = nil
users.map do |user|
favorite_song = user.favorite_song
break if favorite_song
end
请尝试一下
users.map{|user| user.favorite_song}.compact.first
从 Ruby 2.0 开始,您可以使用Enumerator::Lazy#lazy更干净有效地解决这个问题:
users.lazy.map(&:favorite_song).find(&:present?)
这更有效,因为它只会调用favorite_song
用户,直到找到存在的用户。它更简洁,因为它更简洁并且lazy
可以自我记录意图。