如何使ruby函数接受单个项或项集合并执行相同的操作?

如何使ruby函数接受单个项或项集合并执行相同的操作?,ruby,Ruby,我正在尝试编写一个函数,如果它不是集合,则只将该函数应用于一个项,或者将该函数应用于每个集合元素。例如: 用下划线替换空格 这可能吗?这取决于您如何定义“集合”。最自然的选择可能是“任何可枚举的”,甚至是“每个方法的任何内容”。然而,这导致了一个问题,因为字符串也是可枚举的——至少在ruby 1.8中是这样 如果您只需要它来处理阵列,那么很容易: def foo(x) if x.is_a? Array x.map {|item| foo(item)} else # Do

我正在尝试编写一个函数,如果它不是集合,则只将该函数应用于一个项,或者将该函数应用于每个集合元素。例如:

用下划线替换空格
这可能吗?

这取决于您如何定义“集合”。最自然的选择可能是“任何可枚举的”,甚至是“每个方法的任何内容”。然而,这导致了一个问题,因为字符串也是可枚举的——至少在ruby 1.8中是这样

如果您只需要它来处理阵列,那么很容易:

def foo(x)
  if x.is_a? Array
    x.map {|item| foo(item)}
  else
    # Do something with x
  end
end

不确定我是否误读了这个问题。下面将使函数以相同的方式处理单个元素或元素数组。如果参数还不是数组,则Just-array会验证该参数,如果需要,会在末尾撤消该参数

def foo(x)
  x = [x] unless x.is_a? Array
  # do array stuff to x
  return result.size > 1 ? result : result.first
end

您可能对splat操作员感兴趣

def foo(x)
  [*x].map {|item| item.gsub(" ", "_")}
end

不幸的是,这将返回
foo(“a bear”)
作为
[“a_bear”]
,而不是
“a_bear”
,没有数组。

我个人会使用变量args:

def foo(*args)
  args.each { |arg| puts arg }
end

foo("bar")                    # bar
foo("bar", "foobar")          # bar \n foobar
foo(*%w(bar foobar))          # bar \n foobar
a = ["bar", "foobar"]
foo(*a)                       # bar \n foobar
foo("baz", *a)                # baz \n bar \n foobar
a = "bar"
foo(*a)                       # bar
如果您不知道您的参数是字符串还是数组,那么只需在它前面加一个
*


我发现这在处理数组时提供了最大的灵活性,而数组可能是单个值,因为如果我初始化数组,我可以将它们作为参数输入,如果我知道它将是数组或单个参数,则可以安全地传递变量。但它会被散列阻塞。

不太准确;如果x=[]或x==[1]?会发生什么情况?还有一个结果相同的方法:
[x].flatte.map{
def foo(*args)
  args.each { |arg| puts arg }
end

foo("bar")                    # bar
foo("bar", "foobar")          # bar \n foobar
foo(*%w(bar foobar))          # bar \n foobar
a = ["bar", "foobar"]
foo(*a)                       # bar \n foobar
foo("baz", *a)                # baz \n bar \n foobar
a = "bar"
foo(*a)                       # bar