4

私は Erlang を学び始めたばかりで、Erlang のリスト内包表記の構文がとても気に入っています。次に例を示します。

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

この場合、FoggyPlaces「london」および「boston」と評価されます。

Rubyでこれを行う最良の方法は何ですか?

たとえば、次のような配列 (非常に一般的だと思います):

 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}]

私が今まで得た最高のものは次のとおりです。

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

しかし、この場合、値compactを削除するために呼び出す必要nilがあり、例自体は Erlang ほど読みやすくありません。

さらに、Erlang の例では、cityとの両方weatherがアトムです。Rubyでこのように理にかなって見栄えのするものを取得する方法さえわかりません。

4

1 に答える 1

10

まず、データ構造は同等ではありません。Erlang の例と同等の Ruby データ構造は、次のようになります。

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

次に、はい、Ruby にはリスト内包表記もパターン マッチングもありません。したがって、例おそらくより複雑になります。リスト内包表記は、最初にすべての霧の都市をフィルタリングしてから、名前を射影します。Rubyでも同じことをしましょう:

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

ただし、Ruby はオブジェクト中心ですが、抽象データ型を使用しています。よりオブジェクト指向のデータ抽象化を使用すると、コードはおそらく次のようになります

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

悪くないですよね?

于 2012-11-14T13:19:31.480 に答える