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

时间:2010-09-09 19:41:46

标签: ruby

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

用下划线替换空格

foo 'a bear' => 'a_bear'
foo ['a bear', 'a bee'] => ['a_bear', 'a_bee']

这可能吗?

4 个答案:

答案 0 :(得分:1)

这取决于你如何定义“集合”。最自然的选择可能是“任何可枚举的”,甚至是“每种方法的任何东西”。然而,这会导致一个问题,因为字符串也是可枚举的 - 至少在红宝石1.8中。

如果您只需要它来处理数组,那很简单:

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

答案 1 :(得分:1)

我个人会使用变量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

如果您不知道您的参数是字符串还是数组,那么只需在其前面添加*

我发现这在处理数组时提供了最大的灵活性,而数组可能只是一个值,因为我可以输入它们作为参数,如果我正在初始化数组或安全地传入变量,如果我知道它将是一个数组或一个论点。它会扼杀哈希。

答案 2 :(得分:0)

您可能对splat运算符感兴趣

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

不幸的是,如果没有数组,这会将foo("a bear")返回["a_bear"],而不是"a_bear"

答案 3 :(得分:-2)

不确定我是否误读了这个问题。下面将使它成为一个函数将以相同的方式处理单个元素或元素数组。如果它不是一个数组,只需数组 - 如果参数,并在必要时撤消该结论。

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