2012-03-11 30 views
9

有时候我想要一个变量永远是一个数组,无论它是一个标量还是已经是一个数组。强制标量或数组成为一个数组

所以我通常做:

[variable].flatten 

这与红宝石1.8.5,1.8.7,1.9.x中兼容

使用此方法时,variable是一个字符串(variable = "asdf"),它给我["asdf"]。如果它已经是一个数组(variable = ["asdf","bvcx"]),它会给我:["asdf","bvcx"]

有没有人有更好的方法? “更好”意味着更可读,更高效,简洁或以其他方式更有效。

回答

13

我这样做的方式,并认为是标准的方式,使用[*...]

variable1 = "string" 
variable2 = ["element1", "element2"] 

[*variable1] #=> ["string"] 
[*variable2] #=> ["element1", "element2"] 
+1

我不知道lucapette的方式,这似乎工作,但我上面显示的方式工作的速度大约是两倍。 – sawa 2012-03-11 13:22:01

+0

在哪个实现? YARV? – 2012-03-11 20:53:17

+0

@AndrewGrimm是的。 YARV在Ruby 1.9.3中。 – sawa 2012-03-11 22:10:02

0

你可能会需要像Array.eat。大多数其他方法要么在对象上调用#to_a#to_ary。如果你在哪里使用[ obj ].flatten,可能会给出令人惊讶的结果。除非使用level参数调用,否则#flatten也会对嵌套数组进行调整,并会创建数组的额外副本。

主动支持提供Array.wrap,但也称#to_ary,这可能会或可能不会满足您的需要,具体取决于您的需要。

require 'active_support/core_ext/array/wrap' 

class Array 

# Coerce an object to be an array. Any object that is not an array will become 
# a single element array with object at index 0. 
# 
# coercing nil returns an empty array. 
# 
def self.eat(object) 

    object.nil?    and return [] 
    object.kind_of?(Array) and return object 

    [object] 

end 

end # class Array 

a = { a: 3 } 

p [a].flatten  # => [{:a=>3}] 
p [*a]    # => [[:a, 3]] -> OOPS 
p Array  a  # => [[:a, 3]] -> OOPS 
p Array.wrap a  # => [{:a=>3}] 
p Array.eat a  # => [{:a=>3}] 
相关问题