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