我有一个方法可以返回单个对象或对象集合。我希望能够在该方法的结果上运行object.collect,无论它是否是单个对象或集合。我怎么能这样做?
profiles = ProfileResource.search(params)
output = profiles.collect do | profile |
profile.to_hash
end
如果profiles是单个对象,当我尝试对该对象执行collect时,我会收到NoMethodError异常。
答案 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”方法。
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
这样,如果您从搜索中单独返回单个项目,则可枚举方法仍将按预期工作。
这种方式的优势在于它的所有支持都在你的课堂内,而不是在必须多次重复的地方之外。
当然,更好的方法是更改搜索的实现,使其返回一个数组而不管返回多少项。