Search code examples
ruby-on-railsrubystringstring-comparison

Ruby - Trying to compare 2 strings in ruby but getting an error. Unable to figure out what to do


puts "Enter the string"

str = gets.chomp.split("")

i =0  
j = i+1  
l = str.length-1  
for i in str[i..l]  
  k = 0  
  for j in str[j..l-1]  
    if i.bytes==j.bytes  
      k+=1  
    end   
    # p i  
    # p j  
  end  
end  
Error   
Traceback (most recent call last):   
    2: from task4.rb:155:in `<main>'   
    1: from task4.rb:155:in `each'   
task4.rb:157:in `block in <main>': bad value for range (ArgumentError)

Hi, I am a noob in ruby rn. But in the above scenario I am trying to compare i and j to figure out number of occurrence of a alphabet. When I iterate the loop in i and j I am getting the desired output but once I start comparing. It gives an argument error. I have attached images for the reference. Please enlighten me.


Solution

  • It's not the comparison that breaks your program, if you removed it - it still breaks. But if you put some debugging output:

    str = "abc".chomp.split("")
    
    i =0  
    j = i+1  
    l = str.length-1  
    for i in str[i..l]  
      k = 0  
      puts "i:#{i.inspect} j:#{j.inspect} k:#{k.inspect}"
      puts "next range (inner loop): #{j}..#{l-1}"
      puts "next range (outer loop): #{i}..#{l}"
      for j in str[j..l-1]  
        puts "j:#{j}"
      end  
    end  
    
    

    you'll see what's wrong:

    $ ruby test.rb
    i:"a" j:1 k:0
    next range (inner loop): 1..1
    next range (outer loop): a..2
    j:b
    i:"b" j:"b" k:0
    next range (inner loop): b..1
    next range (outer loop): b..2
    test.rb:11:in `block in <main>': bad value for range (ArgumentError)
            from test.rb:6:in `each'
            from test.rb:6:in `<main>'
    
    

    If we focus on the inner loop, before we start it j=1, but after we enter it j becomes the "b" (a string!), and you and second time the loop evaluates the range - it "sees" "b"..2, which makes no sense in the ruby world.

    In essence - you're overwriting your variables, try using different variables for the "captured" elements of the array, e.g:

    str = "abc".chomp.split("")
    
    i =0  
    j = i+1  
    l = str.length-1  
    for character_outer_loop in str[i..l]  
      k = 0  
      puts "i:#{i.inspect} j:#{j.inspect} k:#{k.inspect}"
      puts "next range (inner loop): #{j}..#{l-1}"
      puts "next range (outer loop): #{i}..#{l}"
      for character_inner_loop in str[j..l-1]  
        puts "j:#{j}"
      end  
    end