如何将单个对象转换为ruby中的Enumerable

时间:2008-09-17 02:38:02

标签: ruby

我有一个方法可以返回单个对象或对象集合。我希望能够在该方法的结果上运行object.collect,无论它是否是单个对象或集合。我怎么能这样做?

profiles = ProfileResource.search(params)
output = profiles.collect do | profile |
    profile.to_hash
end

如果profiles是单个对象,当我尝试对该对象执行collect时,我会收到NoMethodError异常。

9 个答案:

答案 0 :(得分:6)

小心使用flatten方法,如果search()返回嵌套数组,则可能会导致意外行为。

profiles = ProfileResource.search(params)
profiles = [profiles] if !profiles.respond_to?(:collect)
output = profiles.collect do |profile|
    profile.to_hash
end

答案 1 :(得分:6)

这是一个班轮:

[*ProfileResource.search(params)].collect { |profile| profile.to_hash }

技巧是splat(*)将单个元素和枚举变为参数列表(在本例中为新数组运算符)

答案 2 :(得分:1)

profiles = [ProfileResource.search(params)].flatten
output = profiles.collect do |profile|
    profile.to_hash
end

答案 3 :(得分:0)

search类的ProfileResource方法中,总是返回一组对象(通常是一个数组),即使它只包含一个对象。

答案 4 :(得分:0)

如果集合是数组,则可以使用此技术

profiles = [*ProfileResource.search(params)]
output = profiles.collect do | profile |
    profile.to_hash
end

这样可以保证您的个人资料始终是一个数组。

答案 5 :(得分:0)

profiles = ProfileResource.search(params)
output = Array(profiles).collect do |profile|
    profile.to_hash
end

答案 6 :(得分:0)

您可以首先使用“pofiles.respond_to?”检查对象是否响应“collect”方法。

来自Programming Ruby

  

obj.respond_to?(   aSymbol,includePriv = false) - >真正   或者是假的

     

如果obj响应,则返回true   给定的方法。私人方法是   仅在搜索时包含在搜索中   可选的第二个参数求值为   真。

答案 7 :(得分:0)

您也可以使用Kernel#Array方法。

profiles = Array(ProfileResource.search(params))
output = profiles.collect do | profile |
    profile.to_hash
end

答案 8 :(得分:0)

另一种方法是认识到Enumerable要求您提供每种方法。

因此。你可以将Enumerable混合到你的班级中,并给它一个假的,每个都有效....

class YourClass
  include Enumerable

  ... really important and earth shattering stuff ...

  def each
    yield(self) if block_given?
  end
end

这样,如果您从搜索中单独返回单个项目,则可枚举方法仍将按预期工作。

这种方式的优势在于它的所有支持都在你的课堂内,而不是在必须多次重复的地方之外。

当然,更好的方法是更改​​搜索的实现,使其返回一个数组而不管返回多少项。