Reputation: 11727
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?
Upvotes: 16
Views: 22237
Reputation: 61
You can use truncate method as well.
'Once upon a time in a world far far away'.truncate(27, separator: ' ')
# => "Once upon a time in a..."
.truncate(200number of characters, separator: ' ')
to do not cut the word in the middle, it will finish when find a space after the number of characters you choose.
Upvotes: 0
Reputation: 898
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
Upvotes: 7
Reputation: 34984
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.
Upvotes: 1
Reputation: 176382
# Ruby >= 1.8.7
$varString.lines.first
# => "my::FIrst::Line"
# Ruby < 1.8.7
$varString.split("\n").first
# => "my::FIrst::Line"
As a side note, avoid to use global (the $
sign) variables.
Upvotes: 39
Reputation: 80065
str = <<DOC1
asrg
aeg
aegfr
DOC1
puts str[0..(str.index("\n")|| -1)]
Avoids reading the whole string in an array. (The ||-1 avoids an error if there is no line ending in the string).EDIT str.lines does not create an array.
Upvotes: 4
Reputation: 12225
$varString.lines.first
Or, if you want to get rid of final newline in resulting string:
$varString.lines.first.chomp
Upvotes: 29
Reputation: 20875
puts $varString.split('\n')[0]
Splits the string on '\n' tokens, and get the first one
Upvotes: 1