首页 > 解决方案 > 为什么 Array#sort 在 OS X 和 Ubuntu 之间的行为不同?

问题描述

我阅读了https://8thlight.com/blog/will-warner/2013/03/26/stable-sorting-in-ruby.html并尝试复制其发现,我得到了一些有趣的结果。这只是非常糟糕的运气,还是我正在做某事?

这就是我在irbOS X 10.11.6 上使用的内容rvm

2.3.1 :001 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 7], [0, 8], [0, 4], [0, 6], [1, 9], [1, 1], [1, 10], [1, 2], [1, 3], [1, 5]]
2.3.1 :002 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 10], [0, 7], [0, 8], [0, 1], [0, 4], [0, 5], [0, 6], [1, 2], [1, 3], [1, 9]]
2.3.1 :003 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 7], [0, 8], [0, 3], [0, 10], [1, 1], [1, 9], [1, 6], [1, 2], [1, 4], [1, 5]]
2.3.1 :004 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 5], [0, 8], [0, 9], [0, 2], [1, 7], [1, 1], [1, 10], [1, 3], [1, 4], [1, 6]]
2.3.1 :005 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 1], [0, 5], [0, 7], [0, 10], [1, 8], [1, 6], [1, 9], [1, 2], [1, 3], [1, 4]]
2.3.1 :006 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 4], [0, 5], [0, 9], [0, 3], [1, 8], [1, 1], [1, 10], [1, 2], [1, 6], [1, 7]]
2.3.1 :007 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 6], [0, 2], [0, 3], [0, 4], [0, 5], [1, 10], [1, 7], [1, 8], [1, 9], [1, 1]]
2.3.1 :008 > RUBY_VERSION
 => "2.3.1"

这些发现与博客文章相符——最终结果没有按照您期望的方式排序,这是有道理的,因为 Ruby 排序并不意味着稳定。

如果我通过 ssh 进入 Ubuntu 16.04 服务器并运行相同的代码,我的数组就会出现排序!

2.3.1 :001 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 2], [0, 4], [0, 6], [0, 7], [0, 8], [0, 9], [0, 10], [1, 1], [1, 3], [1, 5]]
2.3.1 :002 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 1], [0, 2], [0, 4], [0, 5], [0, 6], [0, 8], [0, 10], [1, 3], [1, 7], [1, 9]]
2.3.1 :003 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 1], [0, 2], [0, 6], [0, 10], [1, 3], [1, 4], [1, 5], [1, 7], [1, 8], [1, 9]]
2.3.1 :004 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 1], [0, 3], [0, 9], [0, 10], [1, 2], [1, 4], [1, 5], [1, 6], [1, 7], [1, 8]]
2.3.1 :005 > (1..10).map { |a| [rand(2),a] }.shuffle.sort { |a, b| a[1] <=> b[1] }.sort { |a, b| a[0] <=> b[0] }
 => [[0, 1], [0, 4], [0, 7], [0, 8], [1, 2], [1, 3], [1, 5], [1, 6], [1, 9], [1, 10]]
2.3.1 :006 > RUBY_VERSION
 => "2.3.1"

这种行为是预期的吗?我读过的所有内容都表明 ruby​​ 排序不稳定,如果你稳定排序很重要,你应该实现这样东西。但是,如果这里发生了一些时髦的事情,我很想知道它是什么。

标签: ruby

解决方案


推荐阅读