我想解析stdin文本,并获取结构化数据容器对象。 我每次都很困惑,最后我使用全局变量,ARGF,每个变量和分裂。 我怎么能做得更好?我怎样才能更轻松地阅读和阅读?或者宝石对我有什么帮助?
以下是我丑陋代码的一个案例:
# encoding: utf-8
$DATA = {}
$COUNT = 0
ARGF.each do |line|
col = line.split(nil).map(&:to_i)
if col.count == 1
next
elsif col.count == 2
$DATA[$COUNT][:cut_param] << { :cut_order => col[0], :pick_count => col[1] }
elsif col.count == 3
$COUNT += 1
$DATA[$COUNT] = {
:card_amount => col[0],
:cut_count => col[1],
:needle_order => col[2],
:cut_param => []
}
end
end
答案 0 :(得分:3)
你所得到的并不是太糟糕。也许我会做两件事
case
语句代替elsif
的代码:
@data = []
ARGF.each do |line|
col = line.split.map(&:to_i)
case col.count
when 3
@data << {
:card_amount => col[0],
:cut_count => col[1],
:needle_order => col[2],
:cut_param => []
}
when 2
@data.last[:cut_param] << { :cut_order => col[0], :pick_count => col[1] }
end
end
答案 1 :(得分:0)
这样的事情怎么样?启用模块化并为输出添加更多结构。 (可能也想将OrderData放在DataParser模块中......)
# encoding: utf-8
class OrderData < Struct.new(:card_amount, :cut_count, :needle_order, :cut_param)
# Maybe add functionality if needed (existence checking?)
end
module DataParser
def parse(lines)
# Die if we get invalid arguments
if lines.nil? || lines.length == 0 || !(lines.is_a? Array)
raise ArgumentError, "DataParser::parse Requires a single Array parameter."
end
# Collect up our structured output
output = []
# Iterate over the input array structuring each result
lines.each do |line|
col = line.split.map(&:to_i)
if col.count == 1
next
elsif col.count == 2
output.last.cut_param << { :cut_order => col[0], :pick_count => col[1] }
elsif col.count == 3
output.push(OrderData.new(
:card_amount => col[0],
:cut_count => col[1],
:needle_order => col[2],
:cut_param => []
))
end
end
# Explictly return the output variable instead of the output of the lines
# array interation.
return output
end
end
# If we're run directly, use the command line input for processing
if __FILE__ == $0
order_data = DataParser::parse(ARGV)
puts order_data
end