确定变量是否是值列表中的任何一个的最短/最惯用的方法是什么?

Nei*_*ilS 7 ruby syntax

这似乎是一个非常简单的问题,但是在Ruby中用最短/最惯用的方法重写这个问题是什么?

if variable == :a or variable == :b or variable == :c or variable == :d # etc.
Run Code Online (Sandbox Code Playgroud)

我看到了这个解决方案

if [:a, :b, :c, :d].include? variable
Run Code Online (Sandbox Code Playgroud)

但这并不总是在功能上等同 - 我相信Array#include?实际上看看列表中是否包含变量对象; 它没有考虑到对象可以实现自己的相等测试def ==(other).

正如下面有用的评论员所观察到的那样,这种解释是不正确的.include?确实使用==但它使用==数组中项目的方法.在我的例子中,它是符号,而不是==变量的方法.这就解释了为什么它不等同于我的第一个代码示例.

(举例来说,Rails的Mime::Type实现:request.format == :html可能返回true,但[:html].include?(request.format)会返回false,就像request.formatMime :: Type的实例一样,而不是符号.)

我到目前为止最好的是:

if [:a, :b, :c, :d].select {|f| variable == f}.any?
Run Code Online (Sandbox Code Playgroud)

但对我来说似乎有些麻烦.有没有人有更好的建议?

Pes*_*sto 15

实际上,#include? 确实使用==.如果你这样做,问题就出现了

[:a].include? foo
Run Code Online (Sandbox Code Playgroud)

它检查:a == foo,而不是foo == :a.也就是说,它使用==在Array中的对象上定义的方法,而不是变量.因此,只要确保数组中的对象具有正确的==方法,就可以使用它.

如果这不起作用,您可以通过删除select语句并将块直接传递给any:来简化语句:

if [:a, :b, :c, :d].any? {|f| variable == f}
Run Code Online (Sandbox Code Playgroud)