Ruby:Object.to_a替代品

时间:2008-12-22 10:06:09

标签: ruby

我需要将传入的参数(单个对象或集合)转换为数组。我不知道论点是什么。如果它已经是一个数组,我想保留它,否则从中创建一个单元素数组。我希望同时允许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]

7 个答案:

答案 0 :(得分:45)

使用方法Kernel#Array

Array([1,2,3]) #=> [1, 2, 3]
Array(123) #=> [123]

是的,它起初看起来像是一个类,但这实际上是一个以大写字母开头的方法。

答案 1 :(得分:9)

哇,有人只是暗示了一个非常古老的线索。 :-O但是因为我还没有看到它包含在内,所以为了完整性,我将再增加一条方法:

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)怎么样?