简体   繁体   中英

Ruby: NoMethodError when comparing element in an array

I'm working on a method that takes an array of words as a param and returns an array of arrays, where each subarray contains words that are anagrams of each other. The line while sort_array[i][1]==temp do is throwing undefined method '[]' for nil:NilClass (NoMethodError) and I have no idea why.

def combine_anagrams(words)
sort_array = Hash.new

words.each do |w|
    sort_array[w] = w.split("").sort
end

sort_array = sort_array.sort_by { |w, s| s }

return_array = []
i = 0
while i<sort_array.length do
    temp_array = []
    temp = sort_array[i][1]
    while sort_array[i][1]==temp do
        temp_array += [sort_array[i][0]]
        i+=1
    end
    return_array += [temp_array]
end

return temp_array
end

p combine_anagrams( ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams','scream'] )

It looks like this is because you are incrementing your i variable without checking to make sure you're still in bounds of the sort_array . To see the problem, put an puts statement in your code inside the inner most while loop:

while sort_array[i][1]==temp do
  temp_array += [sort_array[i][0]]
  i+=1
  puts "i is #{i} and the length is #{sort_array.length}"
end

and then run your code and you'll see:

i is 1 and the length is 8
i is 2 and the length is 8
i is 3 and the length is 8
i is 4 and the length is 8
i is 5 and the length is 8
i is 6 and the length is 8
i is 7 and the length is 8
i is 8 and the length is 8
example.rb:15:in `combine_anagrams': undefined method `[]' for nil:NilClass (NoMethodError)

You need to make sure on both while loops that you stay within the bounds of your array, for instance:

while i < sort_array.length && sort_array[i][1]==temp do
end

As a side note, your code is currently only going to return the last temp_array , since you're also resetting that at the beginning of your outer while loop. And, if I understand what problem you're trying to solve you might want to look at group_by available on Array thanks to the Enumerable module:

words = ['cars', 'for', 'potatoes', 'racs', 'four','scar', 'creams','scream']
words.group_by { |word| word.chars.sort }.values
# => [["cars", "racs", "scar"], ["for"], ["potatoes"], ["four"], ["creams", "scream"]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM