Ruby String concatenation - ruby

I have an array
books = ["Title 1", "Title 2", "Title 3"]
I need to iterate through this array and get a variable like this:
#books_read = "Title 1 \n Title 2 \n Title 3"
I tried this bit of code:
books.each do |book|
#books_read += "#{book} \n"
end
puts #books_read
But, the + operator does not concatenate the strings. Any leads on this please.
Cheers!

You can use Array#join: books.join(" \n ").
join(sep=$,) → str
Returns a string created by converting each element of the array to a
string, separated by sep.

You can use join: books.join(" \n ")

Related

Split method in a Do loop to separate string values in an array by whitespace

I have an array:
array = ["John Smith", "Bill Taylor", Troy Tate"]
I am trying to use the split method to print either the first name or last name only from each name in the array. I am using the following, but the array.split(" ") is obviously only splitting the strings into two at the whitespace.
How can I use the '.string' method to only print either the first or last name. Or first character for that matter?
array = ["John Smith", "Bill Taylor", Troy Tate"]
array.each do |array|
puts array.split(" ")
end
Anything like this?
array.each { |name| puts name.split.sample }

Split a string by multiple delimiters

I want to split a string by whitespaces, commas, and dots. Given this input :
"hello this is a hello, allright this is a hello."
I want to output:
hello 3
a 2
is 2
this 2
allright 1
I tried:
puts "Enter string "
text=gets.chomp
frequencies=Hash.new(0)
delimiters = [',', ' ', "."]
words = text.split(Regexp.union(delimiters))
words.each { |word| frequencies[word] +=1}
frequencies=frequencies.sort_by {|a,b| b}
frequencies.reverse!
frequencies.each { |wor,freq| puts "#{wor} #{freq}"}
This outputs:
hello 3
a 2
is 2
this 2
allright 1
1
I do not want the last line of the output. It considers the space as a
word too. This may be because there were consecutive delimiters (,, &, " ").
Use a regex:
str = 'hello this is a hello, allright this is a hello.'
str.split(/[.,\s]+/)
# => ["hello", "this", "is", "a", "hello", "allright", "this", "is", "a", "hello"]
This allows you to split a string by any of the three delimiters you've requested.
The stop and comma are self-explanatory, and the \s refers to whitespace. The + means we match one or more of these, and means we avoid empty strings in the case of 2+ of these characters in sequence.
You might find the explanation provided by Regex101 to be handy, available here: https://regex101.com/r/r4M7KQ/3.
Edit: for bonus points, here's a nice way to get the word counts using each_with_object :)
str.split(/[.,\s]+/).each_with_object(Hash.new(0)) { |word, counter| counter[word] += 1 }
# => {"hello"=>3, "this"=>2, "is"=>2, "a"=>2, "allright"=>1}

How do I repeat the first character of words in a string?

Using Ruby 2.4. I have a string with letters and spaces. For example,
"abc def"
How do I change the string such that I duplicate the first character of each word? That is, the above would become:
"aabc ddef"
because "a" and "d" are the start of the words in the above string. By word, I mean any sequence of characters separated by spaces.
I'd just use gsub to find and double them.
"abc def".gsub(/\b\w/, '\0\0')
=> "aabc ddef"
You can just split the string by each space, and multiply the first character the number of times you need, then append, or concatenate the "initial" word:
p "abc def".split.map { |word| "#{word[0] * 10}#{word}" }.join(' ')
You can try the below snippet
str = "abc def"
index = 0
new_str = ""
str.split.each do | string |
string = string[0] + string
new_str = new_str + string + " "
index = index + 1
end
puts "New string #{new_str}"

Convert a string based on hash values [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I am trying to write a method that takes in a string and a hash and "encodes" the string based on hash keys and values.
def encode(str,encoding)
end
str = "12#3"
encoding = {"1" => "one", "2"=> "two", "3"=> "three"}
I am expecting the output to be "one two three" any char in the string that is not a key in the hash is replaced with an empty string.
Right now my code looks like the following:
def encode(str, encoding)
output = ""
str.each_char do |ch|
if encoding.has_key?(ch)
output += encoding[ch]
else
output += ""
end
end
return output
end
Any help is appreciated
You can use use the form of String#gsub that uses a hash for substitutions, and a simple regex:
str = "12#3"
encoding = {"1"=>"one", "2"=>"two", "3"=>"three"}
First create a new hash that adds a space to each value in encoding:
adj_encoding = encoding.each_with_object({}) { |(k,v),h| h[k] = "#{v} " }
#=> {"1"=>"one ", "2"=>"two ", "3"=>"three "}
Now perform the substitutions and strip off the extra space if one of the keys of encoding is the last character of str:
str.gsub(/./, adj_encoding).rstrip
#=> "one two three"
Another example:
"1ab 2xx4cat".gsub(/./, adj_encoding).rstrip
#=> "one two"
Ruby determines whether each character of str (the /./ part) equals a key of adj_encodeing. If it does, she substitutes the key's value for the character; else she substitutes an empty string ('') for the character.
You can build a regular expression that matches your keys via Regexp.union:
re = Regexp.union(encoding.keys)
#=> /1|2|3/
scan the string for occurrences of keys using that regular expression:
keys = str.scan(re)
#=> ["1", "2", "3"]
fetch the corresponding values using values_at:
values = encoding.values_at(*keys)
#=> ["one", "two", "three"]
and join the array with a single space:
values.join(' ')
#=> "one two three"
As a "one-liner":
encoding.values_at(*str.scan(Regexp.union(encoding.keys))).join(' ')
#=> "one two three"
Try:
def encode(str, encoding)
output = ""
str.each_char do |ch|
if encoding.has_key?(ch)
output += encoding[ch] + " "
else
output += ""
end
end
return output.split.join(' ')
end
str = "12#3"
encoding = {"1" => "one", "2"=> "two", "3"=> "three"}
p encode(str, encoding) #=> "one two three"
If you are expecting "one two three" you just need to add an space to your concat line and before return, add .lstrip to remove the first space.
Hint: You don't need the "else" concatenating an empty string. If the "#" don't match the encoding hash, it will be ignored.
Like this:
#str = "12#3"
#encoding = {"1" => "one", "2"=> "two", "3"=> "three"}
def encode(str, encoding)
output = ""
str.each_char do |ch|
if encoding.has_key?(ch)
output += " " + encoding[ch]
end
end
return output.lstrip
end
# Output: "one two three"
I would do:
encoding = {"1" => "one", "2"=> "two", "3"=> "three"}
str = "12#3"
str.chars.map{|x|encoding.fetch(x,nil)}.compact.join(' ')
Or two lines like this:
in_encoding_hash = -> x { encoding.has_key? x }
str.chars.grep(in_encoding_hash){|x|encoding[x]}.join(' ')

Get content between parenthesis from String object in Ruby

I have a string like this:
Hi my name is John (aka Johnator).
What is the best way to get what comes between the parentheses (including the parentheses)?
You can use String#[] with a regular expression:
a = "Hi my name is John (aka Johnator)"
a[/\(.*?\)/]
# => "(aka Johnator)"
Use [^()]*? for select text in parenthese :
a = "Hi (a(b)c) ((d)"
# => "Hi (a(b)c) ((d)"
a.gsub(/\([^()]*?\)/) { |x| p x[1..-2]; "w"}
"b"
"d"
# => "Hi (awc) (w"
Try this:
str1 = ""
text = "Hi my name is John (aka Johnator)"
text.sub(/(\(.*?\))/) { str1 = $1 }
puts str1
Edit: Didn't read about leaving the parenthesis!

Resources