在 ruby​​ 中使用块设置变量

发布于 2024-08-12 15:38:28 字数 495 浏览 3 评论 0原文

我发现自己在 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 中的块设置变量?

I find myself using PHP-like loops a lot in Ruby and it feels wrong when the rest of the language is so neat. I wind up with code like this:

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

I feel like I should be able to do something like this

conditions_string = zips.each_with_index do |zip, i|

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

end

Is there a 'Neat' way to set a variable with a block in Ruby?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

摇划花蜜的午后 2024-08-19 15:38:28

由于您实际上并未使用 zip 的值,因此我建议

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

但一般来说我建议查看 Enumerable#inject 函数以避免这种循环。

Since you don't actually use the value of zip, I'd suggest

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

but in general I'd suggest looking at the Enumerable#inject function to avoid this kind of loops.

债姬 2024-08-19 15:38:28

我想到的第一件事是:

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'

The first thing I thought of was this:

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

But that can be done with just

a.join ' OR '

And while I think you will need that construct soon, to duplicate your exact example I might just use:

([' npa = ? '] * a.size).join 'OR'
扬花落满肩 2024-08-19 15:38:28

您似乎没有在循环中访问 zip ,因此以下操作应该有效:

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

如果您需要访问 zip ,那么您可以使用:

conditions_string = zips.collect {|zip| 'npa = ?'}.join(' OR ')

You don't seem to be accessing zip in your loop, so the following should work:

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

If you need access to zip, then you could use:

conditions_string = zips.collect {|zip| 'npa = ?'}.join(' OR ')
谜兔 2024-08-19 15:38:28

尽管其他人针对您的具体问题给出了更惯用的解决方案,但实际上有一个很酷的方法 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 的 $_ 那样普遍涵盖所有内容,但它允许您隐式地将方法发送到一个对象。

Although others have given more idiomatic solutions to your specific problem, there's actually a cool method Object#instance_eval, which is a standard trick that many Ruby DSLs use. It sets self to the receiver of instance_eval inside its block:

Short example:

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"

It doesn't pervasively cover everything in the way Perl's $_ does, but it allows you to implicitly send methods to one single object.

余生再见 2024-08-19 15:38:28

在 1.8.7+ 中,您可以使用 each_with_object

它用以下方式替换 DigitalRoss 的“注入”惯用语:

a = %w{hello my friend}  => ["hello", "my", "friend"]
a.each_with_object("") { |v, o| o << v << " NOT " }  => "hello NOT my NOT friend NOT"

In 1.8.7+ you can use each_with_object

It replaces DigitalRoss's 'inject' idiom with this:

a = %w{hello my friend}  => ["hello", "my", "friend"]
a.each_with_object("") { |v, o| o << v << " NOT " }  => "hello NOT my NOT friend NOT"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文