Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang vs Ruby list comprehensions

I just started to learn Erlang, and really like their list comprehension syntax, for example:

Weather = [{toronto, rain}, {montreal, storms}, {london, fog}, {paris, sun}, {boston, fog}, {vancounver, snow}].                          
FoggyPlaces = [X || {X, fog} <- Weather].

In this case, FoggyPlaces will evaluate to "london" and "boston".

What's the best way to do this in Ruby?

For example, an Array like (very common, I believe):

 weather = [{city: 'toronto', weather: :rain}, {city: 'montreal', weather: :storms}, {city: 'london', weather: :fog}, {city: 'paris', weather: :sun}, {city: 'boston', weather: :fog}, {city: 'vancounver', weather: :snow}]

The best I got 'til now is:

weather.collect {|w| w[:city] if w[:weather] == :fog }.compact

But in this case, I have to call compact to remove nil values, and the example itself is not that readable as Erlang.

And even more, in the Erlang example, both city and weather are atoms. I don't even know how to get something that makes sense and looks good like this in Ruby.

like image 645
caarlos0 Avatar asked Dec 26 '22 14:12

caarlos0


1 Answers

First off, your data structures aren't equivalent. The equivalent Ruby data structure to your Erlang example would be more like

weather = [[:toronto, :rain], [:montreal, :storms], [:london, :fog], 
            [:paris, :sun], [:boston, :fog], [:vancouver, :snow]]

Secondly, yes, Ruby doesn't have list comprehensions nor pattern matching. So, the example will probably be more complex. Your list comprehension first filters all foggy cities, then projects the name. Let's do the same in Ruby:

weather.select {|_, weather| weather == :fog }.map(&:first)
# => [:london, :boston]

However, Ruby is centered around objects, but you are using abstract data types. With a more object-oriented data abstraction, the code would probably look more like

weather.select(&:foggy?).map(&:city)

which isn't too bad, is it?

like image 165
Jörg W Mittag Avatar answered Jan 11 '23 07:01

Jörg W Mittag