Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map/Collect first true result

Consider the following

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

In this case, I want the first favorite song I encounter among my users.

Can this be written in a nicer way?

I tried

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

But it returns the first user with a favorite song, rather than the favorite song itself.

like image 953
Niels B. Avatar asked Jul 06 '26 14:07

Niels B.


2 Answers

If the users array isn't too big, your first solution is fine, and can be rewritten like this:

users.map(&:favorite_song).compact.first

You can also modify your second approach as follows:

users.find { |user| user.favorite_song.present? }.favorite_song

Both of these solutions assume that there exists a favorite_song in some user and will raise an exception if there isn't. You can elegantly avoid this with try (Rails only):

users.find { |user| user.favorite_song.present? }.try(:favorite_song)
like image 133
Zach Langley Avatar answered Jul 10 '26 02:07

Zach Langley


What about:

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

Will return user.favorite_song if condition is true otherwise will return users

like image 23
Pierre-Louis Gottfrois Avatar answered Jul 10 '26 03:07

Pierre-Louis Gottfrois



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!