2

私は Ruby で PHP のようなループを頻繁に使用していることに気づきました。言語の残りの部分が非常にきちんとしていると、違和感を覚えます。私は次のようなコードで終わります:

conditions_string = ''

zips.each_with_index do |zip, i|

    conditions_string << ' OR ' if i > 0
    conditions_string << "npa = ?"

end

# Now I can do something with conditions string

こんなことができたらいいなと思います

conditions_string = zips.each_with_index do |zip, i|

    << ' OR ' if i > 0
    << "npa = ?"

end

Rubyでブロックを使用して変数を設定する「きちんとした」方法はありますか?

4

5 に答える 5

4

私が最初に考えたのはこれでした:

a = %w{array of strings}             => ["array", "of", "strings"]
a.inject { |m,s| m + ' OR ' + s }    => "array OR of OR strings"

しかし、それはただで行うことができます

a.join ' OR '

そして、あなたはすぐにその構成が必要になると思いますが、あなたの正確な例を複製するために、私はちょうど使用するかもしれません:

([' npa = ? '] * a.size).join 'OR'
于 2009-12-01T23:24:11.357 に答える
4

実際にはzipの値を使用しないので、お勧めします

zips.map {|zip| "npa = ?" }.join(" OR ")

ただし、一般的には、この種のループを回避するためにEnumerable#inject関数を確認することをお勧めします。

于 2009-12-01T23:25:41.727 に答える
1

zipループ内でアクセスしていないように見えるため、次のように機能するはずです。

conditions_string = (['npa = ?'] * zips.length).join(' OR ')

にアクセスする必要がある場合はzip、次を使用できます。

conditions_string = zips.collect {|zip| 'npa = ?'}.join(' OR ')
于 2009-12-01T23:21:16.183 に答える
1

他の人が特定の問題に対してより慣用的な解決策を提供していますが、実際にはクールな方法Object#instance_evalがあり、これは多くの Ruby DSL が使用する標準的なトリックです。ブロック内selfのレシーバーに設定します。instance_eval

短い例:

x = ''
x.instance_eval do
    for word in %w(this is a list of words)
        self << word  # This means ``x << word''
    end
end
p x
# => "thisisalistofwords"

Perl のようにすべてを網羅するわけではありません$_が、メソッドを 1 つのオブジェクトに暗黙的に送信できます。

于 2009-12-02T09:20:51.947 に答える
0

1.8.7+では使用できますeach_with_object

DigitalRoss の「inject」イディオムを次のように置き換えます。

a = %w{hello my friend}  => ["hello", "my", "friend"]
a.each_with_object("") { |v, o| o << v << " NOT " }  => "hello NOT my NOT friend NOT"
于 2009-12-02T09:05:58.197 に答える