如何将单个对象转换为红宝石中可枚举的对象
时间:2020-03-05 18:57:44 来源:igfitidea点击:
我有一个可以返回单个对象或者对象集合的方法。我希望能够在该方法的结果上运行object.collect,无论它是单个对象还是集合。我怎样才能做到这一点?
profiles = ProfileResource.search(params) output = profiles.collect do | profile | profile.to_hash end
如果配置文件是单个对象,则在尝试对该对象执行collect时会收到NoMethodError异常。
解决方案
回答
profiles = [ProfileResource.search(params)].flatten output = profiles.collect do |profile| profile.to_hash end
回答
在ProfileResource类的search方法中,即使它仅包含一个对象,也总是返回对象的集合(通常是Array)。
回答
谨慎使用扁平化方法,如果search()返回嵌套数组,则可能会导致意外行为。
profiles = ProfileResource.search(params) profiles = [profiles] if !profiles.respond_to?(:collect) output = profiles.collect do |profile| profile.to_hash end
回答
这是一个班轮:
[*ProfileResource.search(params)].collect { |profile| profile.to_hash }
诀窍是splat(*),它将单个元素和枚举数都转换为参数列表(在本例中为新数组运算符)
回答
如果集合是数组,则可以使用此技术
profiles = [*ProfileResource.search(params)] output = profiles.collect do | profile | profile.to_hash end
这样可以保证配置文件始终是一个数组。
回答
profiles = ProfileResource.search(params) output = Array(profiles).collect do |profile| profile.to_hash end
回答
我们可以先使用" pofiles.respond_to?"检查对象是否响应" collect"方法。
从Ruby编程
obj.respond_to?( aSymbol, includePriv=false ) -> true or false Returns true if obj responds to the given method. Private methods are included in the search only if the optional second parameter evaluates to true.
回答
我们也可以使用Kernel#Array方法。
profiles = Array(ProfileResource.search(params)) output = profiles.collect do | profile | profile.to_hash end
回答
另一种方法是认识到Enumerable要求我们提供每个方法。
所以。我们可以将Enumerable混合到班级中,并给每个虚拟人起作用。
class YourClass include Enumerable ... really important and earth shattering stuff ... def each yield(self) if block_given? end end
这样,如果我们从搜索中单独取回单个项目,则可枚举的方法仍将按预期工作。
这种方式的优点是,对它的所有支持都在类内部,而不是在必须多次重复的外部。
当然,更好的方法是更改搜索的实现,以使其无论返回多少项目都返回一个数组。