2

考虑以下

users.collect do |user|
  user.favorite_song.presence
end.compact.first

在这种情况下,我想要在我的用户中遇到的第一首最喜欢的歌曲。

这可以写得更好吗?

我试过了

users.find do |user|
  user.favorite_song.presence
end

但它会返回第一个用户最喜欢的歌曲,而不是最喜欢的歌曲本身。

4

5 回答 5

10

如果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)
于 2013-08-06T11:42:52.127 回答
4

关于什么:

users.each do |user|
  break user.favorite_song if user.favorite_song.present?
end

user.favorite_song如果条件为将返回,true否则将返回users

于 2013-08-06T11:44:34.687 回答
1
favorite_song = nil
users.map do |user|
  favorite_song = user.favorite_song
  break if favorite_song
end
于 2013-08-06T11:41:05.330 回答
0

请尝试一下

users.map{|user| user.favorite_song}.compact.first
于 2013-08-06T11:52:52.213 回答
0

从 Ruby 2.0 开始,您可以使用Enumerator::Lazy#lazy更干净有效地解决这个问题:

users.lazy.map(&:favorite_song).find(&:present?)

这更有效,因为它只会调用favorite_song用户,直到找到存在的用户。它更简洁,因为它更简洁并且lazy可以自我记录意图。

于 2017-02-18T23:50:14.997 回答