3

我有一个接受单个对象或对象集合的方法。检测传入的内容是否可枚举的正确方法是什么?我目前正在执行以下操作(可行,但我不确定这是正确的方法):

def foo(bar)
  if bar.respond_to? :map
    # loop over it
  else
    # single object
  end
end
4

5 回答 5

8

我会用is_a?.

bar.is_a? Enumerable

但是有一个更好的方法来获取单个对象或集合,假设调用者知道他们传入的是哪个对象。使用 splat:

def foo(*args)
  args.each do |arg|
    …
  end
end

然后,您可以将其称为foo(single_arg)foo(arg1, arg2)foo(*argv)

于 2013-07-18T17:23:50.690 回答
4

我取决于您的确切需求,但区分单个对象和Enumerable. 特别是, aHash是一个Enumerable,但在大多数情况下,它应该被视为单个对象。

通常最好区分单个对象和类似数组的参数。这就是 Ruby 经常做的事情。最好的方法是检查是否arg.respond_to? :to_ary. 如果是这样,那么所有方法都Array应该对您可用,如果不将其视为单个对象。

如果您真的想检查Enumerable,您可以测试arg.is_a? Enumerable但考虑 aHash是 an ,枚举数Enumerable也是如此(并且调用它们甚至不会给您一个数组!)Lazymap

于 2013-07-18T17:28:55.907 回答
3

如果您的目的是循环遍历它,那么标准方法是确保它是一个数组。你可以无条件地这样做。

def foo(bar)
  [*bar] # Loop over it. It is ensured to be an array.
end
于 2013-07-18T17:28:54.277 回答
1

一次性处理单件物品或收藏品怎么样?

[*bar].each { |item| puts item }

无论bar是单个项目还是数组或哈希或其他任何东西,这都将起作用。这可能不是使用哈希的最佳选择,但使用数组时效果很好。

于 2013-07-18T17:29:23.243 回答
1

另一种确保某事是 an 的Array方法是使用Array“功能(技术上仍然是一种方法):

def foo(bar)
  Array(bar).map { |o| … }
end

Array将数组保留为数组,并将单个元素转换为数组:

Array(["foo"]) # => ["foo"]
Array("foo")   # => ["foo"]
Array(nil)     # => []
于 2013-07-18T17:33:02.903 回答