BSalunke
BSalunke

Reputation: 11727

How to get first line from String in Ruby?

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

Answers (7)

Lincoln Marcolongo
Lincoln Marcolongo

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.

API doc

Upvotes: 0

Shai Coleman
Shai Coleman

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

Bibek Shrestha
Bibek Shrestha

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

Simone Carletti
Simone Carletti

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

steenslag
steenslag

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

Victor Deryagin
Victor Deryagin

Reputation: 12225

$varString.lines.first

Or, if you want to get rid of final newline in resulting string:

$varString.lines.first.chomp

Upvotes: 29

Vivien Barousse
Vivien Barousse

Reputation: 20875

puts $varString.split('\n')[0]

Splits the string on '\n' tokens, and get the first one

Upvotes: 1

Related Questions