Ruby: How to get the first character of a string - ruby

How can I get the first character in a string using Ruby?
Ultimately what I'm doing is taking someone's last name and just creating an initial out of it.
So if the string was "Smith" I just want "S".

You can use Ruby's open classes to make your code much more readable. For instance, this:
class String
def initial
self[0,1]
end
end
will allow you to use the initial method on any string. So if you have the following variables:
last_name = "Smith"
first_name = "John"
Then you can get the initials very cleanly and readably:
puts first_name.initial # prints J
puts last_name.initial # prints S
The other method mentioned here doesn't work on Ruby 1.8 (not that you should be using 1.8 anymore anyway!--but when this answer was posted it was still quite common):
puts 'Smith'[0] # prints 83
Of course, if you're not doing it on a regular basis, then defining the method might be overkill, and you could just do it directly:
puts last_name[0,1]

If you use a recent version of Ruby (1.9.0 or later), the following should work:
'Smith'[0] # => 'S'
If you use either 1.9.0+ or 1.8.7, the following should work:
'Smith'.chars.first # => 'S'
If you use a version older than 1.8.7, this should work:
'Smith'.split(//).first # => 'S'
Note that 'Smith'[0,1] does not work on 1.8, it will not give you the first character, it will only give you the first byte.

"Smith"[0..0]
works in both ruby 1.8 and ruby 1.9.

For completeness sake, since Ruby 1.9 String#chr returns the first character of a string. Its still available in 2.0 and 2.1.
"Smith".chr #=> "S"
http://ruby-doc.org/core-1.9.3/String.html#method-i-chr

In MRI 1.8.7 or greater:
'foobarbaz'.each_char.first

Try this:
>> a = "Smith"
>> a[0]
=> "S"
OR
>> "Smith".chr
#=> "S"

In Rails
name = 'Smith'
name.first

>> s = 'Smith'
=> "Smith"
>> s[0]
=> "S"

Another option that hasn't been mentioned yet:
> "Smith".slice(0)
#=> "S"

Because of an annoying design choice in Ruby before 1.9 — some_string[0] returns the character code of the first character — the most portable way to write this is some_string[0,1], which tells it to get a substring at index 0 that's 1 character long.

Try this:
def word(string, num)
string = 'Smith'
string[0..(num-1)]
end

If you're using Rails You can also use truncate
> 'Smith'.truncate(1, omission: '')
#=> "S"
or for additional formatting:
> 'Smith'.truncate(4)
#=> "S..."
> 'Smith'.truncate(2, omission: '.')
#=> "S."
While this is definitely overkill for the original question, for a pure ruby solution, here is how truncate is implemented in rails
# File activesupport/lib/active_support/core_ext/string/filters.rb, line 66
def truncate(truncate_at, options = {})
return dup unless length > truncate_at
omission = options[:omission] || "..."
length_with_room_for_omission = truncate_at - omission.length
stop = if options[:separator]
rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
else
length_with_room_for_omission
end
"#{self[0, stop]}#{omission}"
end

Other way around would be using the chars for a string:
def abbrev_name
first_name.chars.first.capitalize + '.' + ' ' + last_name
end

Any of these methods will work:
name = 'Smith'
puts name.[0..0] # => S
puts name.[0] # => S
puts name.[0,1] # => S
puts name.[0].chr # => S

Related

Extract Date from string ruby

I have this string :
Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)
And I want to extract the date which is "06/04/2015". How do i do this in ruby?
I have tried to do something like this:
str[-1..-11]
but didnt work. Any suggestion? Thanks!
str = "Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)"
str.match(/(\d{2}\/\d{2}\/\d{4})/)[0]
#=> "06/04/2015"
This code matches anything that's in the format of 2 numbers/2 numbers/4 numbers and returns it.
If there's a possibility of having XX/XX/XXXX somewhere else in the string, I'd probably use the following code instead:
str = "Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)"
str.match(\(Introduced (\d{2}\/\d{2}\/\d{4})\)$)[0]
#=> "06/04/2015"
This searches for (Introduced XX/XX/XXXX) and grabs the date from that in particular.
Date has a parse method, which happens to just work.
require 'date'
str = "Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)"
p d = Date.parse(str) # => #<Date: 2015-04-06 ((2457119j,0s,0n),+0s,2299161j)>
str[-11..-2] if the position of the date does not change
I agree with Piccolo's comment. Here is a simple regular expression you can try in irb. I recommend experimenting in irb to learn some rudimentary Ruby regular expressions.
For example, /.+([0-9]{2}\/[0-9]{2}\/[0-9]{4}).+/ looks for anything followed by two digits, slash, two digits, slash, four digits, then anything:
$ irb
2.2.0 :001 > s='Rep. Barletta, Lou [R-PA-11] (Introduced 06/04/2015)'
2.2.0 :009 > /.+([0-9]{2}\/[0-9]{2}\/[0-9]{4}).+/ =~ s && $1
=> "06/04/2015"
2.2.0 :010 >
#steenslag's answer looks for valid dates (unlike the other answers), but could still be tripped up:
str = "The first 10 may go 15/15/2015 with Lou (Introduced 06/04/2015)"
Date.parse(str)
#=> #<Date: 2015-05-10 ((2457153j,0s,0n),+0s,2299161j)>
To ensure the date is in the specified format, you could do the following:
require 'date'
def extract_date(str, fmt)
a = str.each_char
.each_cons(10)
.find { |a| Date.strptime(a.join, fmt) rescue nil }
a ? a.join : nil
end
For str as above:
extract_date(str, '%d/%m/%Y')
#=> "06/04/2015"
A second example:
extract_date("15/15/2015", '%d/%m/%Y')
#=> nil

Get last character in string

I want to get the last character in a string MY WAY - 1) Get last index 2) Get character at last index, as a STRING. After that I will compare the string with another, but I won't include that part of code here. I tried the code below and I get a strange number instead. I am using ruby 1.8.7.
Why is this happening and how do I do it ?
line = "abc;"
last_index = line.length-1
puts "last index = #{last_index}"
last_char = line[last_index]
puts last_char
Output-
last index = 3
59
Ruby docs told me that array slicing works this way -
a = "hello there"
a[1] #=> "e"
But, in my code it does not.
UPDATE:
I keep getting constant up votes on this, hence the edit. Using [-1, 1] is correct, however a better looking solution would be using just [-1]. Check Oleg Pischicov's answer.
line[-1]
# => "c"
Original Answer
In ruby you can use [-1, 1] to get last char of a string. Here:
line = "abc;"
# => "abc;"
line[-1, 1]
# => ";"
teststr = "some text"
# => "some text"
teststr[-1, 1]
# => "t"
Explanation:
Strings can take a negative index, which count backwards from the end
of the String, and an length of how many characters you want (one in
this example).
Using String#slice as in OP's example: (will work only on ruby 1.9 onwards as explained in Yu Hau's answer)
line.slice(line.length - 1)
# => ";"
teststr.slice(teststr.length - 1)
# => "t"
Let's go nuts!!!
teststr.split('').last
# => "t"
teststr.split(//)[-1]
# => "t"
teststr.chars.last
# => "t"
teststr.scan(/.$/)[0]
# => "t"
teststr[/.$/]
# => "t"
teststr[teststr.length-1]
# => "t"
Just use "-1" index:
a = "hello there"
a[-1] #=> "e"
It's the simplest solution.
If you are using Rails, then apply the method #last to your string, like this:
"abc".last
# => c
You can use a[-1, 1] to get the last character.
You get unexpected result because the return value of String#[] changed. You are using Ruby 1.8.7 while referring the the document of Ruby 2.0
Prior to Ruby 1.9, it returns an integer character code. Since Ruby 1.9, it returns the character itself.
String#[] in Ruby 1.8.7:
str[fixnum] => fixnum or nil
String#[] in Ruby 2.0:
str[index] → new_str or nil
In ruby you can use something like this:
ending = str[-n..-1] || str
this return last n characters
Using Rails library, I would call the method #last as the string is an array. Mostly because it's more verbose..
To get the last character.
"hello there".last() #=> "e"
To get the last 3 characters you can pass a number to #last.
"hello there".last(3) #=> "ere"
Slice() method will do for you.
For Ex
"hello".slice(-1)
# => "o"
Thanks
Your code kinda works, the 'strange number' you are seeing is ; ASCII code. Every characters has a corresponding ascii code ( https://www.asciitable.com/). You can use for conversationputs last_char.chr, it should output ;.

Replacing a %20 with a space in Ruby

I've currently got a string that reads something like ["green%20books"] and I'd like it to read ["green books"].
I thought Googling for this would yield a result pretty quickly but everyone just wants to turn spaces into %20s. Not the other way around.
Any help would be much appreciated!
Edit:
This is the function I'm working with and I'm confused where in here to decode the URL. I tried removing the URI.encode text but that broke the function.
def self.get_search_terms(search_url)
hash = CGI.parse(URI.parse(URI.encode(search_url)).query) #returns a hash
keywords = []
hash.each do |key, value|
if key == "q" || key == "p"
keywords << value
end
end
keywords
end
you can use the 'unencode' method of URI. (aliased as decode)
require 'uri'
URI.decode("green%20books")
# => "green books"
this will not only replaces "%20" with space, but every uri-encoded charcter, which I assume is what you want.
documentation
CGI::unescape will do what you want:
1.9.2-p320 :001 > require 'cgi'
=> true
1.9.2-p320 :002 > s = "green%20books"
=> "green%20books"
1.9.2-p320 :003 > CGI.unescape(s)
=> "green books"
Another option (as YenTheFirst mentioned) might be URI.decode. However, I read a discussion that it would be deprecated -- although that was in 2010.
Anyway, since you're asking about arrays, you would perhaps map using that method:
ary.map { |s| CGI.unescape(s) }
You can use regular expressions:
string = "green%20books"
string.gsub!('%20', ' ')
puts string

How do I remove a substring after a certain character in a string using Ruby?

How do I remove a substring after a certain character in a string using Ruby?
new_str = str.slice(0..(str.index('blah')))
I find that "Part1?Part2".split('?')[0] is easier to read.
I'm surprised nobody suggested to use 'gsub'
irb> "truncate".gsub(/a.*/, 'a')
=> "trunca"
The bang version of gsub can be used to modify the string.
str = "Hello World"
stopchar = 'W'
str.sub /#{stopchar}.+/, stopchar
#=> "Hello W"
A special case is if you have multiple occurrences of the same character and you want to delete from the last occurrence to the end (not the first one).
Following what Jacob suggested, you just have to use rindex instead of index as rindex gets the index of the character in the string but starting from the end.
Something like this:
str = '/path/to/some_file'
puts str.slice(0, str.index('/')) # => ""
puts str.slice(0, str.rindex('/')) # => "/path/to"
We can also use partition and rpartitiondepending on whether we want to use the first or last instance of the specified character:
string = "abc-123-xyz"
last_char = "-"
string.partition(last_char)[0..1].join #=> "abc-"
string.rpartition(last_char)[0..1].join #=> "abc-123-"

Remove a character at an index position in Ruby

Basically what the question says. How can I delete a character at a given index position in a string? The String class doesn't seem to have any methods to do this.
If I have a string "HELLO" I want the output to be this
["ELLO", "HLLO", "HELO", "HELO", "HELL"]
I do that using
d = Array.new(c.length){|i| c.slice(0, i)+c.slice(i+1, c.length)}
I dont know if using slice! will work here, because it will modify the original string, right?
Won't Str.slice! do it? From ruby-doc.org:
str.slice!(fixnum) => fixnum or nil [...]
Deletes the specified portion from str, and returns the portion deleted.
If you're using Ruby 1.8, you can use delete_at (mixed in from Enumerable), otherwise in 1.9 you can use slice!.
Example:
mystring = "hello"
mystring.slice!(1) # mystring is now "hllo"
# now do something with mystring
$ cat m.rb
class String
def maulin! n
slice! n
self
end
def maulin n
dup.maulin! n
end
end
$ irb
>> require 'm'
=> true
>> s = 'hello'
=> "hello"
>> s.maulin(2)
=> "helo"
>> s
=> "hello"
>> s.maulin!(1)
=> "hllo"
>> s
=> "hllo"
To avoid needing to monkey patch String you can make use of tap:
"abc".tap {|s| s.slice!(2) }
=> "ab"
If you need to leave your original string unaltered, make use of dup, eg. abc.dup.tap.
I did something like this
c.slice(0, i)+c.slice(i+1, c.length)
Where c is the string and i is the index position I want to delete. Is there a better way?

Resources