Как сделать так, чтобы функция ruby ​​принимала отдельный элемент или коллекцию элементов и делала то же самое? - PullRequest
0 голосов
/ 09 сентября 2010

Я пытаюсь написать функцию, которая применила бы функцию только к одному элементу, если это не коллекция, или применила бы эту функцию к каждому из элементов коллекций.Например:

заменить пробелы подчеркиванием

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

Возможно ли это?

Ответы [ 4 ]

1 голос
/ 17 июня 2011

Лично я бы использовал переменные 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

Если вы не знаете, является ли ваш аргумент строкой или массивом, просто добавьте к нему *.

Я считаю, что это дает максимальную гибкость при работе с массивами, которые могут вместо этого быть одним значением, поскольку я могу вводить их в качестве аргументов, если я инициализирую массив или безопасно передам переменную, если я знаю, что это будет либо массив или единственный аргумент. Хотя он захлебнется хешами.

1 голос
/ 09 сентября 2010

Зависит от того, как вы определяете «коллекцию».Наиболее естественным вариантом, вероятно, будет либо «любой перечисляемый», либо даже «что-нибудь с каждым методом».Однако это приводит к проблеме, потому что строки также являются перечисляемыми - по крайней мере, в ruby ​​1.8.

Если вам нужно только работать с массивами, это просто:

0 голосов
/ 10 сентября 2010

Возможно, вас заинтересует оператор splat

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

К сожалению, он вернет foo("a bear") как ["a_bear"], а не "a_bear" без массива.

0 голосов
/ 09 сентября 2010

Не уверен, что я неправильно понял вопрос или нет. Ниже показано, как функция будет обрабатывать как один элемент, так и массив элементов одинаково. Просто array-ifies аргумент, если он еще не массив, и при необходимости отменяет его в конце.

def foo(x)
  x = [x] unless x.is_a? Array
  # do array stuff to x
  return result.size > 1 ? result : result.first
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...