Создайте тестовый файл
Давайте сначала создадим файл для работы.
text =<<-BITTER_END
It was the best of times, it was the worst of times, it was the age of wisdom,
it was the age of foolishness, it was the epoch of belief, it was the epoch of
incredulity, it was the season of Light, it was the season of Darkness, it was
the spring of hope, it was the winter of despair, we had everything before us,
we had nothing before us...
BITTER_END
FName = 'texte.txt'
File.write(FName, text)
#=> 344
Укажите слово для подсчета
target = 'the'
Создайте регулярное выражение
r = /\b#{target}\b/i
#=> /\bthe\b/i
Разрывы слов \b
используются для того, чтобы, например, 'anthem'
не считалось как 'the'
.
Загружать небольшие файлы
Если, как здесь, файл не огромен, вы можете проглотить его:
File.read("texte.txt").scan(r).count
#=> 10
Построчное чтение больших файлов
Если файл настолько велик, что мы хотели бы прочитать его построчно, сделайте следующее.
File.foreach(FName).reduce(0) { |cnt, line| cnt + line.scan(r).count }
#=> 10
or
File.foreach(FName).sum { |line| line.scan(r).count }
#=> 10
учитывая, что Enumerable#sum дебютировал в Руби v2.4.
См. IO::read и IO::foreach. (IO.methodx...
обычно пишется как File.methodx...
. Это разрешено, потому что File
является подклассом IO
, то есть File < IO #=> true
.)
Используйте gsub, чтобы избежать создания временного массива
Первый метод (глотание файла) создает временный массив:
["the", "the", "the", "the", "the", "the", "the", "the", "the", "the"]
к которому применяется count
(он же size
). Один из способов избежать создания этого массива — использовать String#gsub вместо String#scan, как и первый, при использовании без блока возвращает перечислитель:
File.read("texte.txt").gsub(r).count
#=> 10
Это также можно использовать для каждой строки файла.
Это нетрадиционное, но иногда полезное использование gsub
.
person
Cary Swoveland
schedule
28.04.2017