Ruby的2D数组中的奇怪行为

时间:2013-12-06 04:57:09

标签: ruby arrays sorting loops

我正在Ruby中编写一个基数排序实现作为一种自学练习,这里发生了一些非常奇怪的事情。 letters应该是一个2D数组的桶,每个字母对应一个字母(0表示空格/零,1-26表示字母)。出于某种原因,这段代码并没有将我的单词插入到一个字母索引中。它将它插入每个索引。似乎还有某种无限循环阻止它终止,这也很奇怪。

我做错了什么?这是我的代码。

def radix_sort(words)
    letters = Array.new(27, [])
    offset = 'a'.ord
    max_length = words.max_by { |word| word.length }.length

    (max_length-1).downto(0) do |i|
        words.each do |word|
            if word[i] != nil then 
                index = word[i].downcase.ord - offset
                letters[index + 1] << word
            else
                letters[0] << word
            end
        end
        words = letters.flatten
        letters = letters.map { |bucket| bucket.clear }
    end

    words
end

w = ["cat", "dog", "boar", "Fish", "antelope", "moose"]

p radix_sort(w)

1 个答案:

答案 0 :(得分:2)

首先,没有2D数组,只有数组数组。其次,这个:

default_array = [ ]
letters       = Array.new(27, default_array)

只需将default_array引用复制到27个自动创建的值中的每一个,因此letters如下所示:

letters = [
  default_array,
  default_array,
  ...
]

查看letters[0].object_idletters[1].object_id,您会发现它们完全相同。 fine manual甚至可以说:

  

new(size = 0,obj = nil)
  新(数组)
   new(size){| index |阻止}

     

返回一个新数组。

     

[...]当发送size和可选的obj时,会创建一个包含size objobj个副本的数组。 请注意,所有元素都会引用同一个对象letters = Array.new(27) { [ ] }

在最后一句中强调我的。

但是,如果你说:

letters[0].object_id

然后,对于27个初始值中的每一个,块将被执行一次,并且块的每次执行将创建一个全新的阵列。检查letters[1].object_id和{{1}},您会发现它们真的不同。