Вернуть одно значение из каждого вложенного блока, пытаясь использовать 'return' - PullRequest
0 голосов
/ 07 марта 2011
def get_type
  x = [{:type=>'A', :patterns=>['foo.*']}, {:type=>'B', :patterns=>['bar.*']}]

  name = 'foo.txt'

  result = x.each { |item|
    item[:patterns].each { |regex|
      puts "Checking #{regex} against #{name}"
      if !name.match(regex).nil?
        puts "Found match: #{item[:type]}"
        return item[:type]
      end
    }
  }
end

result = get_type
puts "result: #{result}"

Ожидаемый результат:

Checking foo.* against foo.txt
Found match: A
result: A

Однако все, что я вижу, это:

Checking foo.* against foo.txt
Found match: A

Моя текущая работа заключается в следующем:

def get_type
  x = [{:type=>'A', :patterns=>['foo.*']}, {:type=>'B', :patterns=>['bar.*']}]

  name = 'foo.txt'

  result = []
  x.each { |item|
    item[:patterns].each { |regex|
      puts "Checking #{regex} against #{name}"
      if !name.match(regex).nil?
        puts "Found match: #{item[:type]}"
        result << item[:type]
      end
    }
  }
  result[0] unless result.empty?
end

Почему не работает первый подход? или, может быть, это «работает», я просто не понимаю, почему я не получаю то, что ожидал.

Ответы [ 2 ]

2 голосов
/ 07 марта 2011

Могу ли я предложить рефакторинг?ваш код выглядит неуклюже, потому что вы используете циклы each (обязательно), когда вам на самом деле нужен map + first (функционал).Поскольку перечислимые в Ruby не ленивы, это было бы неэффективно, поэтому люди обычно строят абстракцию Enumerable#map_detect (или find_yield, или find_first, или map_first):

def get_type_using_map_detect(name)
  xs = [{:type => 'A', :patterns => ['foo.*']}, {:type => 'B', :patterns => ['bar.*']}]
  xs.map_detect do |item|
    item[:patterns].map_detect do |regex|
      item[:type] if name.match(regex)
    end
  end
end

Это возможноРеализация метода:

module Enumerable
  # Like Enumerable#map but return only the first non-nil value
  def map_detect
    self.each do |item|
      if result = (yield item)
        return result
      end
    end
    nil
  end
end
1 голос
/ 07 марта 2011

Работает нормально для меня.Вы на самом деле вызываете его с

result = get_type puts "result: #{result}"

?Потому что это не должно работать вообще, хотя я предполагаю, что есть строка, которая была съедена, когда вы опубликовали это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...