data = [ " 64 40 64 41 144 144\r\n", " 68 40 64 41 144 144\r\n", " 72 41 64 41 144 144\r\n", " 76 41 64 41 144 144\r\n", " 128 41 64 41 144 144\r\n", " 132 41 64 42 144 144\r\n", " 136 41 64 42 144 144\r\n", " 140 41 64 42 144 144\r\n"]
re = /\s (\d )\s (\d )/
dlm = []
data.each do |arr|
val = arr.scan(re).flatten.reject(&:empty?).map(&:to_i)
unless val.empty?
d = {}
d["x"] = val[0]
d["y"] = val[1]
d["z"] = val[2]
d["m"] = val[3]
d["n"] = val[4]
d["o"] = val[5]
dlm.append(d)
end
end
I need the above code in one line with ruby. Can someone please help with this?
CodePudding user response:
You can write that as follows.
keys = ["x", "y", "m", "n", "o"]
data.map { |s| keys.zip(s.scan(/\d /).map(&:to_i)).to_h }
#=> [{"x"=>64, "y"=>40, "m"=>64, "n"=>41, "o"=>144},
# {"x"=>68, "y"=>40, "m"=>64, "n"=>41, "o"=>144},
# {"x"=>72, "y"=>41, "m"=>64, "n"=>41, "o"=>144},
# {"x"=>76, "y"=>41, "m"=>64, "n"=>41, "o"=>144},
# {"x"=>128, "y"=>41, "m"=>64, "n"=>41, "o"=>144},
# {"x"=>132, "y"=>41, "m"=>64, "n"=>42, "o"=>144},
# {"x"=>136, "y"=>41, "m"=>64, "n"=>42, "o"=>144},
# {"x"=>140, "y"=>41, "m"=>64, "n"=>42, "o"=>144}]
You could of course remove the line defining keys
by substituting out the variable keys
in the second line.
Here are the steps for the first two elements of data
that are passed to the block by map
:
s = data[0]
#=> " 64 40 64 41 144 144\r\n"
a = s.scan(/\d /)
#=> ["64", "40", "64", "41", "144", "144"]
b = a.map(&:to_i)
#=> [64, 40, 64, 41, 144, 144]
c = keys.zip(b)
#=> [["x", 64], ["y", 40], ["m", 64], ["n", 41], ["o", 144]]
c.to_h
#=> {"x"=>64, "y"=>40, "m"=>64, "n"=>41, "o"=>144}
s = data[1]
#=> " 68 40 64 41 144 144\r\n"
a = s.scan(/\d /)
#=> ["68", "40", "64", "41", "144", "144"]
b = a.map(&:to_i)
#=> [68, 40, 64, 41, 144, 144]
c = keys.zip(b)
#=> [["x", 68], ["y", 40], ["m", 64], ["n", 41], ["o", 144]]
c.to_h
#=> {"x"=>68, "y"=>40, "m"=>64, "n"=>41, "o"=>144}
CodePudding user response:
Ruby does not require line breaks. They are always optional and can always be replaced with either whitespace, an expression separator, or a keyword.
Which means you can always write any Ruby program in one line by simply removing the line breaks:
data = [ " 64 40 64 41 144 144\r\n", " 68 40 64 41 144 144\r\n", " 72 41 64 41 144 144\r\n", " 76 41 64 41 144 144\r\n", " 128 41 64 41 144 144\r\n", " 132 41 64 42 144 144\r\n", " 136 41 64 42 144 144\r\n", " 140 41 64 42 144 144\r\n"]; re = /\s (\d )\s (\d )/; dlm = []; data.each do |arr| val = arr.scan(re).flatten.reject(&:empty?).map(&:to_i); unless val.empty? then d = {}; d["x"] = val[0]; d["y"] = val[1]; d["z"] = val[2]; d["m"] = val[3]; d["n"] = val[4]; d["o"] = val[5]; dlm.append(d) end end
There you go. Your code in one line.