Как избежать ошибки `nil` при попытке соединить строки из разных строк - PullRequest
0 голосов
/ 01 февраля 2019

У меня есть файл, подобный следующему:

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

Я хочу объединить дату и следующую строку, содержащую слово "risk", и присвоить ее переменной.

Iиметь следующий код.

require 'date'

File.foreach("file.txt",sep="\n") do |line|
    if (DateTime.strptime(line.strip, '%Y-%m-%d %H:%M:%S') rescue nil)
     date = line.strip  #Here I'm storing the date in variable "date"
     next
    end

    risk = line[/.*risk.*/]
    next unless not (risk.nil?)
    output = date + risk
    p output
end

И я получаю эту ошибку:

NoMethodError: undefined method `+' for nil:NilClass
        from (irb):3333:in `block in irb_binding'
        from (irb):3325:in `foreach'
        from (irb):3325
        from /usr/bin/irb:11:in `<main>'

Когда я перехватываю строку, содержащую "risk" и хочу объединить ее с датой, хранящейся в переменнойdate, содержимое этой переменной nil.

Я не знаю, когда date изменится на nil.Что я делаю неправильно?Как я могу сохранить дату, чтобы объединить ее позже, когда появится строка, содержащая слово "risk"?

1 Ответ

0 голосов
/ 01 февраля 2019
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"] 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...