应用转换后修改行范围
我想编写一个kiba转换,允许我为特定行数插入相同的信息。在这 case我有一个包含子标题的xls文件,这个子标题也包含数据,如下所示:
Client: John Doe, Code: 1234
qty, date, price
1, 12/12/2017, 300.00
6, 12/12/2017, 300.00
total: 2100
Client: Nick Leitgeb, Code: 2345
qty, date, price
1, 12/12/2017, 100.00
2, 12/12/2017, 200.00
2, 12/12/2017, 50.00
total: 600
Client: …..
为了提取相关数据,我使用下一个转换,它返回与所提供的两个正则数据集中至少一个正则表达式匹配的行 (日期或'客户'字样)
transform, SelectByRegexes regex: [/\d+\/\d+\/\d+/, /Client:/], matches: 1
这将给我下一个结果:
Client: John Doe, Code: 1234
1, 12/12/2017, 300.00
6, 12/12/2017, 300.00
Client: Nick Leitgeb, Code: 2345
1, 12/12/2017, 100.00
2, 12/12/2017, 200.00
2, 12/12/2017, 50.00
…..
现在我拥有了我想要的信息,我需要复制客户端和每个子行的代码,并删除子标题
John Doe, 1234, 1, 12/12/2017, 300.00
John Doe, 1234, 6, 12/12/2017, 300.00
Nick Leitgeb, 2345, 1, 12/12/2017, 100.00
Nick Leitgeb, 2345, 2, 12/12/2017, 200.00
Nick Leitgeb, 2345, 2, 12/12/2017, 50.00
我能想到的唯一方法就是直接在source
或pre_process
块中进行,但需要进行转换
之前用过的是为了显示必要的数据,是否可以在source / pre_process块中使用转换类?
或者在转换中操纵多行?
答案 0 :(得分:3)
Kiba作者在这里!感谢您使用Kiba。你是对的,你可以从专业的source
实现这一目标,但我个人更喜欢使用以下模式:
last_seen_client_row = nil
logger = Logger.new(STDOUT)
transform do |row|
# detect "Client/Code" rows - pseudo code, adjust as needed
if row[0] =~ /\AClient:\z/
# this is a top-level header, memorize it
last_seen_client_row = row
logger.info "Client boundaries detected for client XXX"
next # remove the row from pipeline
else
# assuming you are working with arrays (I usually prefer Hashes though!) ; make sure to dupe the data to avoid
last_seen_client_row.dup + row
end
end
您当然可以将该块转换为更易测试的类,我建议您对行检测非常严格,以确保检测到格式的任何更改并快速失败。
希望这有帮助!