2

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

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

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

4

9 回答 9

6

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

profiles = ProfileResource.search(params)
profiles = [profiles] if !profiles.respond_to?(:collect)
output = profiles.collect do |profile|
    profile.to_hash
end
于 2008-09-17T02:53:15.540 回答
6

这是一个衬垫:

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

诀窍是 splat (*) 将单个元素和可枚举转换为参数列表(在本例中为新数组运算符)

于 2008-09-17T03:00:29.843 回答
1
profiles = [ProfileResource.search(params)].flatten
output = profiles.collect do |profile|
    profile.to_hash
end
于 2008-09-17T02:45:46.230 回答
0

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

于 2008-09-17T02:47:45.540 回答
0

如果集合是一个数组,你可以使用这个技术

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

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

于 2008-09-17T03:00:45.710 回答
0
profiles = ProfileResource.search(params)
output = Array(profiles).collect do |profile|
    profile.to_hash
end
于 2008-09-17T03:01:19.873 回答
0

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

来自Ruby 编程

obj.respond_to?(aSymbol, includePriv=false) -> true or false

如果 obj 响应给定的方法,则返回 true。仅当可选的第二个参数的计算结果为 true 时,私有方法才会包含在搜索中。

于 2008-09-17T03:14:44.913 回答
0

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

profiles = Array(ProfileResource.search(params))
output = profiles.collect do | profile |
    profile.to_hash
end
于 2008-09-17T10:03:31.967 回答
0

另一种方法是实现 Enumerable 要求您提供 each 方法。

所以。你可以将 Enumerable 混入你的班级,并给它一个虚拟的每个工作......

类 YourClass
  包括可枚举

  ......非常重要和惊天动地的东西......

  定义每个
    产量(自我)如果block_given?
  结尾
结尾

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

这种方式的优点是对它的所有支持都在您的班级内部,而不是在必须多次复制的外部。

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

于 2008-09-19T16:28:51.247 回答