Для определения количества абзацев нет необходимости создавать массив и определять его размер.Вместо этого можно напрямую работать со строкой, создав счетчик и посчитав количество сгенерированных им элементов (после некоторой очистки содержимого файла).Это можно сделать с помощью нетрадиционной (но очень полезной) формы метода String # gsub .
Code
def count_paragraphs(fname)
(File.read(fname).gsub(/ +$/,'') << "\n\n").gsub(/\S\n{2,}/).count
end
Примеры
Сначала создадим текстовый файл.
str =<<BITTER_END
Now is the time
for all good
Rubiest to take
a break.
Oh, happy
day.
One for all,
all for one.
Amen!
BITTER_END
# " \n\nNow is the time\nfor all good\nRubiest to take\na break.\n \n \nOh, happy\nday.\n\nOne for all,\nall for one.\n\n \nAmen!\n"
Обратите внимание на встроенные пробелы.
FNAME = 'temp'
File.write(FNAME, str)
#=> 128
Теперь протестируйте метод с этим файлом.
count_paragraphs(FNAME)
#=> 4
Еще один:
count_paragraphs('oliver.txt')
#=> 61
Объяснение
первый шаг - работа с плохо сформированным текстом путем удаления пробелов непосредственно перед новыми строками:
File.read(fname).gsub(/ +$/,'')
#=> "\n\nNow is the time\nfor all good\nRubiest to take\na break.\n\n\nOh, happy\nday.\n\nOne for all,\nall for one.\n\n\nAmen!\n"
Далее добавляются две строки, чтобы мы могли определитьвсе абзацы, включая последний, содержат непробельный символ, за которым следуют два или более символов новой строки. 1 .
Обратите внимание, что файлы, содержащие только пробелы и символы новой строки, содержат нулевые абзацы.
Если известно, что файл не содержит неверно сформированного текста, рабочую строку метода можно упростить до:
(File.read(fname) << "\n\n").gsub(/\S\n{2,}/).count
См. Перечислимый # count и IO # read .(Поскольку File.superclass #=> IO
, read
также является экземпляром метода класса File
, и кажется, что он чаще вызывается в этом классе, чем в IO
.)
Обратите внимание, что String#gsub
безблок возвращает перечислитель (к которому применяется Enumerable#count
),
В сторону: я считаю, что эта форма gsub
была бы более широко использована, если бы она просто имела отдельное имя, такое как pattern_match
.Называть его gsub
кажется неправильным, поскольку оно не имеет ничего общего с «заменой», «глобальным» или иным образом.
1 Я пересмотрел свой первоначальный ответ, чтобы иметь дело с плохо сформированным текстом, ипри этом заимствовал идею @ Kimmo о требовании совпадений для включения непробельного символа.