如何将单个对象转换为ruby中可枚举的对象

时间:2021-07-05 07:22:27

I have a method that can return either a single object or a collection of objects. I want to be able to run object.collect on the result of that method whether or not it is a single object or a collection already. How can i do this?

我有一个方法可以返回单个对象或对象集合。我想要能够运行对象。无论它是单个对象还是集合,都要收集该方法的结果。我该怎么做呢?

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

If profiles is a single object, I get a NoMethodError exception when I try to execute collect on that object.

如果概要文件是一个单独的对象,那么当我尝试在该对象上执行collect时,会得到一个NoMethodError异常。

9 个解决方案

#1


6  

Careful with the flatten approach, if search() returned nested arrays then unexpected behaviour might result.

小心使用flatten方法,如果search()返回嵌套数组,那么可能会出现意想不到的行为。

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

#2


6  

Here's a one Liner:

这是一个一个衬套:

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

The trick is the splat (*) that turns both individual elements and enumerables into arguments lists (in this case to the new array operator)

诀窍在于splat(*),它将单个元素和可枚举数都转换为参数列表(在本例中为新数组操作符)

#3


1  

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

#4


0  

In the search method of the ProfileResource class, always return a collection of objects (usually an Array), even if it contains only one object.

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

#5


0  

If the collection is an Array you could use this technique

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

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

That would guaranteed your profiles is always an array.

这将保证您的概要文件始终是一个数组。

#6


0  

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

#7


0  

You could first check to see if the object responds to the "collect" method by using "pofiles.respond_to?".

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

From Programming Ruby

从Ruby编程

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

obj.respond_to吗?(aSymbol, contains v=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.

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

#8


0  

You can use the Kernel#Array method as well.

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

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

#9


0  

Another way is to realise that Enumerable requires that you supply an each method.

另一种方法是认识到可枚举要求您提供每个方法。

So. you COULD mix in Enumerable to your class and give it a dummy each that works....

所以。你可以混合可列举的类,并给它一个虚拟工作的每个....

class YourClass
  include Enumerable

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

  def each
    yield(self) if block_given?
  end
end

This way, if you get back a single item on its own from the search, the enumerable methods will still work as expected.

这样,如果您从搜索中返回一个单独的项,那么enumerable方法仍然可以正常工作。

This way has the advantage that all the support for it is inside your class, not outside where it has to be duplicated many many times.

这种方法的优点是,所有对它的支持都在类内,而不是在必须多次重复的类外。

Of course, the better way is to change the implementation of search such that it returns an array irrespective of how many items is being returned.

当然,更好的方法是更改search的实现,以便无论返回多少项,它都返回一个数组。

#1


6  

Careful with the flatten approach, if search() returned nested arrays then unexpected behaviour might result.

小心使用flatten方法,如果search()返回嵌套数组,那么可能会出现意想不到的行为。

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

#2


6  

Here's a one Liner:

这是一个一个衬套:

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

The trick is the splat (*) that turns both individual elements and enumerables into arguments lists (in this case to the new array operator)

诀窍在于splat(*),它将单个元素和可枚举数都转换为参数列表(在本例中为新数组操作符)

#3


1  

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

#4


0  

In the search method of the ProfileResource class, always return a collection of objects (usually an Array), even if it contains only one object.

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

#5


0  

If the collection is an Array you could use this technique

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

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

That would guaranteed your profiles is always an array.

这将保证您的概要文件始终是一个数组。

#6


0  

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

#7


0  

You could first check to see if the object responds to the "collect" method by using "pofiles.respond_to?".

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

From Programming Ruby

从Ruby编程

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

obj.respond_to吗?(aSymbol, contains v=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.

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

#8


0  

You can use the Kernel#Array method as well.

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

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

#9


0  

Another way is to realise that Enumerable requires that you supply an each method.

另一种方法是认识到可枚举要求您提供每个方法。

So. you COULD mix in Enumerable to your class and give it a dummy each that works....

所以。你可以混合可列举的类,并给它一个虚拟工作的每个....

class YourClass
  include Enumerable

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

  def each
    yield(self) if block_given?
  end
end

This way, if you get back a single item on its own from the search, the enumerable methods will still work as expected.

这样,如果您从搜索中返回一个单独的项,那么enumerable方法仍然可以正常工作。

This way has the advantage that all the support for it is inside your class, not outside where it has to be duplicated many many times.

这种方法的优点是,所有对它的支持都在类内,而不是在必须多次重复的类外。

Of course, the better way is to change the implementation of search such that it returns an array irrespective of how many items is being returned.

当然,更好的方法是更改search的实现,以便无论返回多少项,它都返回一个数组。