Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get first line from String in Ruby?

Tags:

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?

like image 642
BSalunke Avatar asked Nov 18 '11 10:11

BSalunke


People also ask

How do you get the first element of a string in Ruby?

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 .

What does .first mean in Ruby?

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.

How do you break a line in Ruby?

\r\n should probably do the trick.


2 Answers

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
like image 74
Shai Coleman Avatar answered Oct 09 '22 04:10

Shai Coleman


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.

like image 21
Bibek Shrestha Avatar answered Oct 09 '22 04:10

Bibek Shrestha