2

在比较 Ruby 字符串时,我注意到一些意外行为。我将在下面写:

2.3.1 :011 >   '5.6' >= '5.5'
  => true
2.3.1 :012 >   '5.6' >= '5.7'
  => false
2.3.1 :013 >   '5.6' >= '5.6.1'
  => false
2.3.1 :014 >   '5.6' <= '5.6.1'
  => true
2.3.1 :016 >   '4.6.1' <= '5.6'
  => true
2.3.1 :017 >   '4.6.1' >= '5.6'
  => false

我在网上看到人们Gem::Version.new()用来比较语义版本的几个地方。不过,这不是我的问题。谁能向我解释一下 Ruby 是如何在没有任何库帮助的情况下比较语义版本字符串的?当我用数字比较运算符比较两个字符串时会发生什么?

从上面的测试我想我可以确认它不是简单地比较每个字符串的第一个/最后一个字符的 ascii 值。它也没有使用字符串长度作为我所期望的主要比较。

4

2 回答 2

2

它检查字符串中每个单独字符的序号。它会在同一索引上第一次出现不匹配时停止。序数越高,字符“越大” 。基本上,它类似于:

first_string.chars.map(&:ord) >= second_string.chars.map(&:ord)

正如评论中所指出的,这不会导致自然排序,因此人们为什么使用Gem::Version

'11' > '9' # => false
于 2017-05-25T14:15:08.883 回答
1

它正在比较纯字符串。

对于一个字符串的所有字符都在第二个字符串的开头找到的字符串......但第二个字符串的长度较长,较短的字符串被认为小于。

否则逐个比较字符,直到一个字符串的位置“x”中的字符不等于第二个字符串的位置“x”中的字符,在这些情况下,字母数字序列中较早的字符被认为小于.

'cat' < 'caterpillar' 
=> true

'cow' < 'caterpillar' 
=> false

如果版本号超过一位,您不能依靠它来正确比较语义版本......所以

'5.10' >= '5.9'
=> false

(这不是人们所希望的)

于 2017-05-25T14:16:04.500 回答