I have a string variable in Ruby as follows:
puts $varString.class
puts "##########"
puts $varString
the output of the code above is:
String
##########
my::FIrst::Line
this id second line
sjdf kjsdfh jsdf
djsf sdk fxdj
I need to get only the first line from the string variable (e.g. my::FIrst::Line
).
How can I get it?
In Ruby, we can use the built-in chr method to access the first character of a string. Similarly, we can also use the subscript syntax [0] to get the first character of a string. The above syntax extracts the character from the index position 0 .
The first() is an inbuilt method in Ruby returns an array of first X elements. If X is not mentioned, it returns the first element only. Syntax: range1.first(X) Parameters: The function accepts X which is the number of elements from the beginning. Return Value: It returns an array of first X elements.
\r\n should probably do the trick.
first_line = str[/.*/]
This solution seems to be the most efficient solution in terms of memory allocation and performance.
This uses the str[regexp]
form, see https://ruby-doc.org/core-2.6.5/String.html#method-i-5B-5D
Benchmark code:
require 'stringio'
require 'benchmark/ips'
require 'benchmark/memory'
str = "test\n" * 100
Benchmark.ips do |x|
x.report('regex') { str[/.*/] }
x.report('index') { str[0..(str.index("\n") || -1)] }
x.report('stringio') { StringIO.open(str, &:readline) }
x.report('each_line') { str.each_line.first.chomp }
x.report('lines') { str.lines.first }
x.report('split') { str.split("\n").first }
x.compare!
end
Benchmark.memory do |x|
x.report('regex') { str[/.*/] }
x.report('index') { str[0..(str.index("\n") || -1)] }
x.report('stringio') { StringIO.open(str, &:readline) }
x.report('each_line') { str.each_line.first.chomp }
x.report('lines') { str.lines.first }
x.report('split') { str.split("\n").first }
x.compare!
end
Benchmark results:
Comparison:
regex: 5099725.8 i/s
index: 4968096.7 i/s - 1.03x slower
stringio: 3001260.8 i/s - 1.70x slower
each_line: 2330869.5 i/s - 2.19x slower
lines: 187918.5 i/s - 27.14x slower
split: 182865.6 i/s - 27.89x slower
Comparison:
regex: 40 allocated
index: 120 allocated - 3.00x more
stringio: 120 allocated - 3.00x more
each_line: 208 allocated - 5.20x more
lines: 5064 allocated - 126.60x more
split: 5104 allocated - 127.60x more
An alternate to @steenslag's answer would be to use StringIO to get only the first line.
str = <<DOC1
asrg
aeg
aegfr
DOC1
puts StringIO.open(str, &:readline)
If the String is huge, this avoids splitting the string into a large array and reads only the first line. Note, it throws an EOFError if the string is empty.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With