How do I remove the original string when using each_char? - ruby

My code is:
def LetterChanges(str)
str.each_char {|x| print x.next!}
end
LetterChanges("hello")
Which returns:
"ifmmp" => "hello"
How do I get it to only return "ifmmp"? Any help would be greatly appreciated.

"hello".gsub(/./, &:next)
# => "ifmmp"

def LetterChanges(str)
str.chars.map(&:next).join("")
end
LetterChanges("hello")
# => "ifmmp"
or
def LetterChanges(str)
str.size.times{|i| str[i] = str[i].next }
str
end
LetterChanges("hello")
# => "ifmmp"

puts str;
This should do it for you.

The solution is easy:
def LetterChanges(str)
puts str.chars.map(&:next).join
end
but I'd suggest you to refactor it to let puts out. This way you don't hardcode the print of the value and you just make it return the string so that the user of the method can do whatever he wants with that value:
def LetterChanges(str)
str.chars.map(&:next).join
end
and then you can just do:
puts LetterChanges("hello")
# => "ifmmp"

Related

How do I center all of my puts statements in a program without applying the center method to each string?

So I have this code:
puts "hey".center(150)
puts "yo".center(150)
puts "sup".center(150)
How do I make this shorter and more concise? I was thinking of editing the original puts method?
You can just define a method like this:
def my_puts(str)
puts str.center(150)
end
And use it like:
my_puts "hey"
my_puts("yo")
You can use an iterator.
["hey", "yo", "sup"].each { |word| puts word.center(150) }
puts %w{hey yo sup}.map { |str| str.center(150) }

Implementing dry-run in ruby script

anybody know how to implement dry-run option in Ruby?
I need something like this, but only for ruby
https://serverfault.com/questions/147628/implementing-dry-run-in-bash-scripts
I've tried this, but part after else doesn't work:
DRY_RUN = true
def perform(*args)
command = args
if DRY_RUN
command.each{|x| puts x}
else
command.each {|x| x}
end
end
perform("puts 'Hello'")
Thanks for any idea in advance.
P.S I don't want use something like system("ruby -e \"puts 'Hello'\"")
This could help:
def perform(*commands)
commands.each { |x| DRY_RUN ? puts(x) : eval(x)}
end
It results in:
DRY_RUN = true
perform("puts 'Hello'")
puts 'Hello'
=> ["puts 'Hello'"]
DRY_RUN = false
perform("puts 'Hello'")
Hello
=> ["puts 'Hello'"]

Capitalize Second Word in a String (ruby)

I'm trying to create a method to capitalize the second word in a string. The code below works, but I was wondering if there are other ways to do this:
def camelcase(string)
tmp = string.split
tmp[1].capitalize!
tmp.join('')
end
def camelcase(string)
string.gsub(/\s(\w)/) { |match| $1.capitalize }
end
camelcase("foo bar baz") #=> "fooBarBaz"
Or you might wanna take a look at the camelcasemethod that comes with ActiveSupport::Inflector (see: http://apidock.com/rails/String/camelize)
def camelcase(string)
string.sub(/\s.*/) { |s| s.delete(' ').capitalize}
end
puts camelcase("foo bar bas")
=> "fooBarbaz"
You could use tap which "Yields x to the block, and then returns x" according to the docs. In this case capitalize! modifies x in place before being returned to the method chain for further processing by join.
def camelcase(string)
string.split.tap { |words| words[1].capitalize! }.join
end
camelcase('foo bar baz')
=> "fooBarbaz"
Try this:
s = "foo bar"
s.sub(/\s(\w)/) { $1.capitalize } # => "fooBar"

Make an array in Ruby

I am very beginner in Ruby and probably the question is too easy but well, I've already spent some time on it and couldn't find a solution.
My Ruby script takes a number (ex 10) and a name (ex Vincent). What I want is to make an array looking like
Vincent0
Vincent1..
Vincent9
I can't figure a way to make it..
def arrayfy(string, number)
arr = []
0.upto(number-1) do |i|
arr << "#{string}#{i}"
end
return arr
end
Update: To add these as variables to the class
class Foo
def arrayfy(string, number)
0.upto(number-1) do |i|
var_string = "##{string}#{i}"
var_symbol = var_string.to_sym
self.instance_variable_set(var_symbol, "")
end
end
end
Array.new(10) {|i| "Vincent#{i}"}
gives you
["Vincent0", "Vincent1", "Vincent2", "Vincent3", "Vincent4", "Vincent5",
"Vincent6", "Vincent7", "Vincent8", "Vincent9"]
The documentation for Array is available at http://www.ruby-doc.org/core/classes/Array.html (googling for Array RDoc will give you the URL).
The bit in the braces ({|i| "Vincent#{i}"}) is called a block. You'll definitely want to learn about them.
Using Array.new with a block (docs):
def create_array(count, name)
Array.new(10) { |i| "#{name}#{i} }
end
Using Enumerable#reduce (docs):
def create_array(count, name)
(0...count).reduce([]) { |m,i| m << "#{name}#{i}" }
end
Or using Enumerable#each_with_object (docs):
def create_array(count, name)
(0...count).each_with_object([]) { |i,a| a << "#{name}#{i}" }
end
Using it:
# Using the array (assigning to variables)
array = create_array(10, 'Vincent') # => ['Vincent0', 'Vincent1', 'Vincent2' ...]
name = array[1] # => 'Vincent1'
Just for the record, a solution in a more functional style:
>> def arrayify(str, n)
.. ([str] * n).zip(0...n).map(&:join)
.. end
#=> nil
>> arrayify('Vincent', 10)
#=> ["Vincent0", "Vincent1", "Vincent2", "Vincent3", "Vincent4", "Vincent5", "Vincent6", "Vincent7", "Vincent8", "Vincent9"]
def array_maker(number, string)
result = []
for i in 0..number do
result << "#{string}#{i}"
end
result
end

Return a single value from a nested each block, trying to use 'return'

def get_type
x = [{:type=>'A', :patterns=>['foo.*']}, {:type=>'B', :patterns=>['bar.*']}]
name = 'foo.txt'
result = x.each { |item|
item[:patterns].each { |regex|
puts "Checking #{regex} against #{name}"
if !name.match(regex).nil?
puts "Found match: #{item[:type]}"
return item[:type]
end
}
}
end
result = get_type
puts "result: #{result}"
Expected output:
Checking foo.* against foo.txt
Found match: A
result: A
However, all I see is:
Checking foo.* against foo.txt
Found match: A
My current work around is this:
def get_type
x = [{:type=>'A', :patterns=>['foo.*']}, {:type=>'B', :patterns=>['bar.*']}]
name = 'foo.txt'
result = []
x.each { |item|
item[:patterns].each { |regex|
puts "Checking #{regex} against #{name}"
if !name.match(regex).nil?
puts "Found match: #{item[:type]}"
result << item[:type]
end
}
}
result[0] unless result.empty?
end
Why doesn't the first approach work? or maybe it is 'working', I just don't understand why I'm not getting what I'd expect.
May I suggest a refactor? your code looks kind of clunky because you are using each loops (imperative) when you in fact need a map+first (functional). As Ruby enumerables are not lazy this would be inefficient, so people usually build the abstraction Enumerable#map_detect (or find_yield, or find_first, or map_first):
def get_type_using_map_detect(name)
xs = [{:type => 'A', :patterns => ['foo.*']}, {:type => 'B', :patterns => ['bar.*']}]
xs.map_detect do |item|
item[:patterns].map_detect do |regex|
item[:type] if name.match(regex)
end
end
end
This is a possible implementation of the method:
module Enumerable
# Like Enumerable#map but return only the first non-nil value
def map_detect
self.each do |item|
if result = (yield item)
return result
end
end
nil
end
end
Works fine for me. Are you actually invoking it with
result = get_type puts "result: #{result}"
? Because that shouldn't work at all, though I'm assuming there's a linefeed that got eaten when you posted this.

Resources