强制标量或数组成为数组

时间:2012-03-11 09:42:27

标签: ruby

有时我希望变量始终是一个数组,无论是标量还是数组。

所以我通常这样做:

[variable].flatten

与ruby-1.8.5,1.8.7,1.9.x兼容。

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

有没有人有更好的方法? “更好”意味着在其他方面更具可读性,更高性能,更简洁或更有效。

3 个答案:

答案 0 :(得分:15)

Array(variable)

应该做的伎俩。它使用鲜为人知的Kernel#Array方法。

答案 1 :(得分:13)

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

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

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

答案 2 :(得分: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}]