2

I created a simple method that sorts characters in a string and returns true if "b" is within three (or fewer) characters after an "a" and vice-versa.

Here it is below:

def near_ab(string)
  arr = string.split("")
  a_position = arr.each_with_index.select {|i| arr[i] == "a"}
  b_position = arr.each_with_index.select {|i| arr[i] == "b"}

  if a_position - b_position <= 3      #arr[a] - arr[b] == 3
     return true
 else 
     return false
 end

end

However, after running it I get the following error:

    `[]': no implicit conversion of Array into Integer (TypeError)

Why is it giving me this error and how should I approach resolving it?

0

2 Answers 2

3

The method each_with_index maps the second argument as the index.

Use this instead:

arr.each_with_index.select {|element, i| arr[i] == "a"}

A better way to accomplish what you want:

def near_ab(string)
  arr = string.split("")
  a_position = arr.index('a') # Array#index returns the index of the first element that match `'a'` in this case
  b_position = arr.index('b')

  if (a_position - b_position).abs <= 3      #arr[a] - arr[b] == 3
    return true
  else 
    return false
  end
end

near_ab('hallo, ich bin Jonas!') # => returns false

(you can copy-paste this in your console to try it out)

Sign up to request clarification or add additional context in comments.

3 Comments

I get a new error after changing it to this: undefined method `<=' for [["a", 1]]:Array (NoMethodError)
That's exactly the point: The "select" statement above returns an Array. It seems the "<=" method is not defined for Array Objects and BTW I assume that you don't want to compare the Arrays. If you really want to do it like this you may add a map {|a| a[1]}after the select statement: arr.each_with_index.select {|element, i| arr[i] == "a"}.map{|a| a[1]}
Huh. Forget the map. I just tried and it doesn't work as well. I'd really consider to do it in a different way. This all looks quite ugly. Sorry for the misleading comment above.
1

Why not use the String#index method? each_with_index needs two arguments as already said. select provides you with an Array that you can't compare by simply using <=, and that's the reason for the error.

I'd use something like:

def near_ab(string)
     a_position = string.index('a')
     b_position = string.index('b')

    (a_position - b_position).abs <= 3·
end

puts near_ab('abcde')
puts near_ab('acdeb')
puts near_ab('acdefb')

BTW, I don't see any relation to Rails in your question.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.