我需要将传入的参数(单个对象或集合)转换为数组。我不知道论点是什么。如果它已经是一个数组,我想保留它,否则从中创建一个单元素数组。我希望同时允许method(:objs => obj)
和method(:objs => [obj1, obj2])
这似乎是最好的方式(Array#to_a返回self):
arg = arg.to_a
但红宝石文档说 Object#to_a
很快就会过时。有方便的替换吗?
还有什么比这简洁?
arg = arg.respond_to?(:to_a) ? arg.to_a : [arg]
答案 0 :(得分:45)
使用方法Kernel#Array:
Array([1,2,3]) #=> [1, 2, 3]
Array(123) #=> [123]
是的,它起初看起来像是一个类,但这实际上是一个以大写字母开头的方法。
答案 1 :(得分:9)
arg = [*arg]
如果参数已经是一个数组(因此删除了一个嵌套级别)或者创建一个参数数组,这将抛出该参数:
arg = [1,2,3]
[*arg] #=> [1, 2, 3]
arg = 1
[*arg] #=> [1]
答案 2 :(得分:2)
似乎只推荐使用Object.to_a
,删除默认to_a
并强制每个类定义自己的(Hash.to_a
)。
self.to_a #=> -:1: warning: default `to_a' will be obsolete
"hello".to_a #=> ["hello"]
Time.new.to_a #=> [39, 54, 8, 9, 4, 2003, 3, 99, true, "CDT"]
h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300 }
h.to_a #=> [["a", 100], ["c", 300], ["d", 400]]
如果您的参数是Object
的实例,请尝试:
Hash.new(obj).to_a
@Daniel [对奥利维尔的评论]:重点是我不知道论证是什么。如果它已经是一个数组,我想保留它,否则创建一个单元素数组。
如果是这种情况,请尝试:
obj = [obj] if !obj.is_a?(Array)
答案 3 :(得分:2)
如果更适合问题,你可以采取鸭子打字方式,列出你需要的所有方法,并检查对象是否已经拥有它们,如果没有,使它成为一个数组:
[:[], :each, :etc...].all? { |m| obj.respond_to? m } ? obj : [obj]
优点是你给对象一个机会来实现索引访问的自己的语义。
答案 4 :(得分:2)
我做了很多,总是使用:
arg = [arg] unless arg.is_a?(Array)
虽然如果你知道你永远不会将数组作为单独的参数传递,你也可以这样做:
arg = [arg].flatten
答案 5 :(得分:1)
我不确定这是否有帮助,但我经常需要的不是arg是一个数组,而是arg响应每个。
arg = [arg] unless arg.respond_to? :each
答案 6 :(得分:0)
Array.new(1,arg)怎么样?