Преобразование массива, возвращенного IO :: readlines , в строку, а затем подсчет количества раз, когда строка появляется в этой строке, может быть выполнено, но это не тот подход, который любой опытный Rubiest сделал бывозьмите.
Сначала давайте создадим файл "winners.txt"
.
arr = ["Raiders", "Bears", "bearskin rug", "Chargers", "my bugbears", "bears"]
str = arr.join("\n")
#=> "Raiders\nBears\nbearskin rug\nChargers\nmy bugbears\nbears"
filename = "winners.txt"
File.write(filename, str)
#=> 53 (characters written)
и получим название команды:
team = gets.chomp
#=> "bears"
См. IO #напишите . 1
Подход, предложенный в вопросе и предоставленный в другом ответе, выглядит следующим образом:
array = IO.readlines(filename)
#> ["Raiders\n", "Bears\n", "bearskin rug\n", "Chargers\n", "my bugbears\n", "bears"]
str = array.to_s
#=> "[\"Raiders\\n\", \"Bears\\n\", \"bearskin rug\\n\", \"Chargers\\n\", \"my bugbears\\n\", \"bears\"]"
a = str.scan(team)
#=> ["bears", "bears", "bears"]
a.size
#=> 3
, что неверно.Мы могли бы обойти эти проблемы, но более традиционный подход заключается в следующем:
team = gets.downcase.chomp
#=> "bears"
a = File.readlines(filename)
#=> ["raiders\n", "bears\n", "bearskin rug\n", "chargers\n", "my bugbears\n", "bears"]
a.count { |s| s.downcase.match?(/\b#{team}\b/) }
#=> 2
, который дает правильный ответ, поскольку a[1]
и a[-1]
(и только эти элементы) совпадают.Регулярное выражение гласит: «соответствует разрыв слова (\b
), за которым следует значение team
, за которым следует еще один разрыв слова».
Однако мы можем улучшить это.Нет необходимости создавать временный массив, a
.Вместо этого мы используем IO :: foreach , который читает файл построчно и, когда используется без блока, возвращает перечислитель:
enum = File.foreach(filename)
#=> #<Enumerator: File:foreach("winners.txt")>
Мы можем видеть значения, которыебудет сгенерирован enum
путем преобразования его в массив:
enum.to_a
#=> ["raiders\n", "\n", "bears\n", "\n", "bearskin rug\n", "\n", "chargers\n",
# "\n", "my bugbears\n", "\n", "bears\n"]
Продолжение,
enum.count { |s| s.downcase.match?(/\b#{team}\b/) }
#=> 2
Обычно два метода объединяются в цепочку:
File.foreach(filename).count { |s| s.downcase.match?(/\b#{team}\b/) }
#= 2
1 Я использовал File
в качестве приемника для некоторых методов, определенных в классе IO
.Это обычно делается и работает, потому что File.superclass #=> IO
.