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"
Related
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) }
I have:
foos.each do |foo|
unless foo
puts "Foo is missing"
next
end
# rest of business logic goes here
end
I would like to write the last part of it better, something like
{ puts "Foo is missing"; next } unless foo
Unfortunately, this does not work. Does anybody know a way to write two (blocks of) commands inline with if condition?
Just use parentheses:
(puts 'a'; puts 'b') if true
#=> a
#=> b
What you are looking for can be done with parentheses:
(puts "Foo is missing"; next) unless foo
But in this particular case, it is better to write:
next puts "Foo is missing" unless foo
Use begin..end block:
begin puts "Foo is missing"; next end unless foo
foos.each { |foo| foo or ( puts "Foo is missing"; next )
# the rest of the business logic goes here
}
You can use the or syntax
[1,2,3].each do |x|
puts 'two' or next if x == 2
puts x
end
#=> 1
#=> "two"
#=> 3
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"
i have this test in ruby I'm trying to implement
require "silly_blocks"
describe "some silly block functions" do
describe "reverser" do
it "reverses the string returned by the default block" do
result = reverser do
"hello"
end
result.should == "olleh"
end
it "reverses each word in the string returned by the default block" do
result = reverser do
"hello dolly"
end
result.should == "olleh yllod"
end
end
here's the method
def do_reverse(str)
str = str.split
first_str = str[0].reverse
second_str= str[1]
if (second_str == nil)
str = first_str.to_s
else
second_str = str[1].reverse
str = (first_str +" "+ second_str)
end
end
what is the best way that i could implement it . when i try to rake the test it failed , but the method by itself return the reserve. i'm just a little confused.
Try this code:
def reverser
yield.split.map { |word| word.reverse}.join(" ")
end
Here's an easy way of doing what you're looking for, with specs.
# lib/reverse_words.rb
def reverse_words(phrase)
return '' if phrase.nil?
words = phrase.split
phrase.split.map(&:reverse!).join(' ')
end
def reverser
reverse_words(yield)
end
# spec/reverse_words_spec.rb
describe "#reverse_words" do
context "when single word" do
subject { reverse_words("hello") }
it { should == "olleh" }
end
context "when multiple words" do
subject { reverse_words("hello dolly") }
it { should == "olleh yllod" }
end
context "when nil" do
subject { reverse_words(nil) }
it { should == '' }
end
context "when empty" do
subject { reverse_words('') }
it { should == '' }
end
end
Note that the reverser spec simply makes use of the behavior that reverse_words has already been specced to pass.
describe "#reverser" do
subject do
reverser do
"this is a test"
end
end
it { should == reverse_words("this is a test") }
end
Here's a less wordy reverse_words spec:
describe "#reverse_words (less wordy)" do
# counterintuitive keys as answers to support the nil case
cases = { "olleh" => "hello",
"olleh yllod" => "hello dolly",
'' => nil,
'' => ''
}
cases.each_pair do |expected, input|
context "#{input} should equal #{expected}" do
subject { reverse_words(input) }
it { should == expected }
end
end
end
This works. The data you want is stored in "yield".
def reverser
yield.gsub(/\w+/) { |w| w.each_char.to_a.reverse.join }
end
My reverser method:
def reverser
# yield is the string given in the block
words = yield.split(' ')
final = []
words.each do |word|
final.push(word.reverse)
end
final.join(' ')
end
So. I came here looking for information on how to do this also. As the language wasn't clear. I went and looked offsite, and found enough information to pass the tests.
So, blocks are those things between curly braces that sometimes follow functions in ruby, such as
list.each {|i| i.reverse}
So what the spec is doing is trying to figure out what happens when it does:
rerverser {"hello"}
Putting yield in a function just returns whatever is in the block, so
def print_block
puts yield
end
print_block {"Hello world."}
#=> "Hello world"
Then you can just manipulate yield like you would manipulate any argument. There's a lot more to blocks. Here's a good place to start, but that's all you need to know to solve the exercise if you've solved all of Test First's learn_ruby exercises up until now.
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.