str =<<_
QWWWQV27
ETYUM
2019-01-29 03:20:07
KJJD_990
RP04MMB High risk YUZZP
HHLPPD
2019-01-23 12:34:13
CDF55UHM11
UYRP566_I Low risk ABCX
_
FNAME = 'temp'
File.write(FNAME, str)
#=> 144
require 'date'
Мы начнем с определения двух процедур, каждый из которых имеет один аргумент, line
, который будет строкой файла после line.strip!
.
date_r = Proc.new { |line| DateTime.strptime(line,
'%Y-%m-%d %H:%M:%S') rescue false }
#=> #<Proc:0x00005784561a3b28@(irb):567>
risk_r = Proc.new { |line| line.match? /\brisk\b/i }
#=> #<Proc:0x00005784561c5610@(irb):569>
Далее используйте Массив # цикл для создания перечислителя enum
.Каждый раз, когда p = enum.next
выполняется, один из двух процедур date_r
и risk_r
будут присвоены переменной p
, сначала date_r
, затем risk_r
, затем date_r
и так далее, навсегда.Оба процесса возвращают true
или false
.
enum = [date_r, risk_r].cycle
#=> #<Enumerator: [#<Proc:0x00005784561a3b28@(irb):567>,
#<Proc:0x00005784561c5610@(irb):569>]:cycle>
p = enum.next # initialize p to date_r
#=> #<Proc:0x00005784561a3b28@(irb):567>
File.foreach(FNAME).with_object([]) do |line, arr|
line.strip!
if p.call(line)
arr << line
p = enum.next
end
end.each_slice(2).map(&:join)
#=> ["2019-01-29 03:20:07RP04MMB High risk YUZZP",
# "2019-01-23 12:34:13UYRP566_I Low risk ABCX"]
Обратите внимание, что перед выполнением .each_slice(2).map(&:join)
,
File.foreach(FNAME).with_object([]) do |line, arr|
...
end
#=> ["2019-01-29 03:20:07", "RP04MMB High risk YUZZP",
# "2019-01-23 12:34:13", "UYRP566_I Low risk ABCX"]