根據文檔,#delete_at
返回該索引處的元素。
a = ["ant", "bat", "cat", "dog"]
a.delete_at(2) #=> "cat"
a #=> ["ant", "bat", "dog"]
a.delete_at(99) #=> nil
我加了一些調試語句向您展示在每一步發生的,假設極限是4:
@results = [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1], [1, 1]]
@results.each_with_index do |r, i|
puts "RESULT: #{r.to_s}"
puts "INDEX: #{i}"
@results.delete_at(i) if r.size < 4
puts "ARRAY: #{@results.to_s}"
end
RESULT: [1, 1, 1, 1]
INDEX: 0
ARRAY: [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1], [1, 1]]
RESULT: [1, 1, 1, 1]
INDEX: 1
ARRAY: [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1], [1, 1]]
RESULT: [1, 1, 1]
INDEX: 2
ARRAY: [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1]]
# @results == [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1]]
正如你可以看到,原本在索引2的元素已被刪除。因爲在迭代時正在修改@results
,所以索引3不再存在,和索引2已被分析。這就是爲什麼你不應該在遍歷它時修改一個對象。
理想情況下,您要使用#delete_if
。類似於以!
結尾的方法,#delete_if
將根據塊(作爲參數)的條件修改數組(不返回結果的副本)。下面是你將如何實現方法:
def check_results(limit)
@results.delete_if { |arr| arr.length < limit }
end
@results = [ ['foo', 'bar'], ['bizz', 'bazz'], ['kaboom'] ]
check_results(2)
# => @results == [ ['foo', 'bar'], ['bizz', 'bazz'] ]
如果你不想修改@results
,那麼我建議類似的方法,#reject
。同樣,@results
將不會被修改,而是返回結果的副本。
def check_results(limit)
@results.reject { |arr| arr.length < limit }
end
@results = [ ['foo', 'bar'], ['bizz', 'bazz'], ['kaboom'] ]
check_results(2)
# => [ ['foo', 'bar'], ['bizz', 'bazz'] ]
# => @results == [ ['foo', 'bar'], ['bizz', 'bazz'], ['kaboom'] ]
你好。我編輯了我的答案,包括_why_您遇到問題。我包含調試語句。請看看它。我也爲您的問題提供替代方案/解決方案:-) – onebree