0

在这里,我试图了解如何Array#shuffle!处理数组对象。所以我开始在我的IRB

[1,2,3]
#=> [1, 2, 3]
[1,2,3].shuffle!
#=> [3, 1, 2]

在上面的代码中,我理解了它是如何工作的。下面我试图用更难的方式从每个角落看到它。

[1,2,5]
#=> [1, 2, 5]
[1,2,5]<<[1,2,5]
#=> [1, 2, 5, [1, 2, 5]]

直到现在我都很好。

[1, 2, 5, [1, 2, 5]].shuffle!
#=> [5, 1, 2, [1, 2, 5]]

使用上面的代码,我感到困惑。所以下面的问题出现在我的脑海中:

  • (a) 为什么shuffle!不递归工作?正如我所料,内部数组的输出[1, 2, 5]也将被洗牌。但没有发生。

  • (b) 为什么shuffle!不对元素数组进行洗牌[1, 2, 5],而只1, 2, 5,对数组的元素有效[1, 2, 5, [1, 2, 5]]?我认为输出会是[[1, 2, 5],5, 1, 2]. 那么为什么元素数组没有改变它的位置,而普通元素只改变了它的位置呢?

编辑:

它显示的非常有趣的行为:

a=[1,2,4]
#=> [1, 2, 4]
a<<[7,8]
#=> [1, 2, 4, [7, 8]]
a.shuffle!
#=> [[7, 8], 1, 4, 2]
a.shuffle!
#=> [4, 1, [7, 8], 2]
a.shuffle!
#=> [[7, 8], 2, 1, 4]
irb(main):006:0>

洗牌真的遵循任何顺序还是随机洗牌?

4

5 回答 5

2

a)shuffle!改变数组中对象的顺序,这可以是任何东西的集合,所以该方法不能假设里面的东西也可以或应该被打乱。

b)我真的不明白这个问题与 a)有何不同。你能解释更多你认为令人困惑的地方吗?

于 2013-02-21T09:09:34.573 回答
2

a) 为什么会shuffle!递归执行?它作用于它传递的对象,在您的示例中,它是一个包含 4 个项目的数组——它将它们打乱。其中一个是数组的事实既不存在也不存在,其中一个可能是一头驴子。

b)它确实对数组元素进行了洗牌,你应该不止一次地尝试过你的小 IRB 测试,你会发现数组只是没有机会移动。

关于您的编辑,您到底想在这里展示什么,我根本没有看到任何有趣的行为?没有模式,随机播放是伪随机的。

于 2013-02-21T09:09:44.210 回答
0

我敢肯定你可以想象这样一种情况,你需要打乱一组顺序很重要的数组的顺序。在这种情况下,shuffle 非常方便,如果您的需求发生变化,使用 shuffle 方法很容易实现递归 shuffle。但是,如果 Ruby 仅包含递归 shuffle,您将不得不编写原始的非递归 shuffle 方法的逻辑,并且无法使用递归 shuffle 方法优雅地实现解决方案。我认为大多数语言更喜欢使用简单、通用的方法而不是更复杂的方法。

于 2013-05-25T17:44:14.417 回答
0

If you indeed want arrays to be shuffled recursively, there is no problem:

# encoding: utf-8

a = [1,2,3]
a << [6,7,8]

class Array
  alias shuffle_orig shuffle
  def shuffle
    self.shuffle_orig.map { |e| e.respond_to?(:shuffle) ? e.shuffle : e }
  end
end


3.times do
  p a.shuffle
end

Which results in:

#⇒ [2, [8, 6, 7], 3, 1]
#⇒ [3, 1, [7, 6, 8], 2]
#⇒ [1, [8, 7, 6], 3, 2]

The bang version may be monckey-patched as well.

于 2013-02-21T10:54:39.573 回答
0
a=[1,2,4]
#=> [1, 2, 4]
a<<[7,8]

a.each_with_index do |element, index|

  puts "Index: #{index} element: #{element}"
end

随着a<<[7,8]您将新对象附加到a数组中。该对象将具有唯一索引。Shuffle 方法使用这个索引来达到它的目的。

Index: 0 element: 1
Index: 1 element: 2
Index: 2 element: 4
Index: 3 element: [7, 8]

附加的数组[7,8]被视为 1 个对象,因此其内部的元素不会像数组中的元素一样被洗牌a

于 2013-02-21T14:15:10.013 回答