0

I am trying to write a method that takes in a string that will have no spaces. All I want it to do is to return "bug" when the character in the string is a letter [A-Za-z] and to return "ant" if it's any other character.

def Letter(str)
    (0..str.length).to_a do |index|
        if str[index].chr =~ /[A-Za-z]/ ##I think this is where things are going wrong.
            puts "bug"
        else
            puts "ant"
        end
    end
end 

Does anyone have any idea how to fix this? I keep getting arrays of consecutive numbers.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
theamateurdataanalyst
  • 2,794
  • 4
  • 38
  • 72
  • `=~` [is the correct operator to compare against a regex](http://stackoverflow.com/questions/5781362/ruby-operator), not the `=` assignment operator. – Michael Berkowski Sep 11 '14 at 01:11
  • Still getting an array of numbers, but thanks for the correction! – theamateurdataanalyst Sep 11 '14 at 01:14
  • Sounds like homework to me. – the Tin Man Sep 11 '14 at 02:43
  • 1
    To make your code work, you need to replace (1) `to_a` with `each` (2) `(0..str.length)` with either `(0..str.length-1)` or `(0...str.length)` (three dots) and (3) `str[index].chr` with `str[index]`. (2) is because, if `str = "cat"`, `(0..str.length) => (0..3)`, and when `index` gets to `3`, `str[3] => nil`, causing `"ant"` to be printed at the end, when it shouldn't be. @Amadan shows you the Ruby way to approach this problem. He also suggests some coding conventions to follow. I'll add one more: indent two spaces. – Cary Swoveland Sep 11 '14 at 03:28
  • @the Tin Man Not homework. Just self practice. Plus I showed all my steps so let me know if I am not using proper etiquette and I will make sure to improve my question next time. – theamateurdataanalyst Sep 11 '14 at 03:41

2 Answers2

3

Rewritten

def letter(str)
  str.each_char.map do |char|
    (char =~ /[[:alpha:]]/) ? 'bug' : 'ant'
  end
end

In your code, you are trying to print "bug" or "ant"; but you're returning (0..str.length).to_a. This function will return an array of bugs and ants. It is also made more Rubyish:

  • methods should be in snake_case (lowercase, with underscores between words)
  • iterating over strings is easier with each_char
  • it's fine with [A-Za-z], but [[:alpha:]] is both clearer and handles Unicode stuff.
  • since we're testing each character, you know it's going to be one character long, so you don't need the start of line and end of line anchors.
Amadan
  • 191,408
  • 23
  • 240
  • 301
-1
def letter(str)
    str.chars.each do |x|
        puts x=~ /[A-Za-z]/ ? "bug" : "ant"
    end
end 
  • First things first, in your loop your are trying to convert a range into an array.

    (0..str.length).to_a

str.length returns a number, therefore making it into an array will give you an array of numbers. Hence your problem.

  • Second, you have to have brackets around your /a-zA-Z/ regex

  • Third, use the ternary operator. It's great for small if statements. Heres the syntax:

    boolean ? "if boolean is true this code will execute" : "else this code will"

  • Fourth, use the .each methods, ruby is loved partly because of the simplicity of loops and iterating!

Happy coding!

Schylar
  • 774
  • 1
  • 5
  • 13
  • This won't work. `return` will immediately exit the method as soon as the ternary statement returns its value in the first iteration. `each` isn't going to iterate over the values of `str.chars` and *return* an array of "bug" and "ant" variables, it only iterates. – the Tin Man Sep 11 '14 at 02:46
  • I was unsure if he wanted to only output "bug" once or for each iteration that matched the regex. My fault, I fixed the code accordingly. – Schylar Sep 11 '14 at 03:50
  • No, that still won't work. `each` won't return what you think it will. Run your code in IRB and look at what's returned by the method. – the Tin Man Sep 11 '14 at 17:13
  • You are correct, @theTinMan, however `.each` yields exactly what I think it will. I forgot to print it out over each iteration. Thanks! – Schylar Sep 11 '14 at 18:19
  • Well, be careful with not answering the OP's question. The requirement is a method that *returns* the values. – the Tin Man Sep 11 '14 at 22:54