簡體   English   中英

為什么 ruby​​ 將 1 和 0 的字母數字字符串排序為二進制?

[英]Why does ruby sort Alphanumeric strings with 1's and 0's as binary?

我有一個數組["Q10", "Q100", "Q1000", "Q1000a", "Q1001", "Q98"] 排序后,我得到以下結果:

['Q100', 'Q1000', 'Q1000a','Q98', 'Q10', 'Q1001'].sort
["Q10", "Q100", "Q1000", "Q1000a", "Q1001", "Q98"]

由於這種行為,我無法正確排序 ActiveRecord 對象。 我有一個Question模型,它有一個字段label 我需要根據標簽對其進行排序。 因此,帶有標簽Q1將排在第一位,帶有標簽Q1a的問題將緊隨Q1a ,依此類推。 我使用 ActiveRecord 的順序與上述數組示例中的描述類似。 我使用 postgresql 作為我的數據庫。

現在我有3個問題。

  1. 為什么字母數字字符串排序會這樣?
  2. 如何在不使用排序塊的情況下實現所需的排序?
  3. 如何在 ActiveRecord 中實現這種排序?

如果你的數組是

arr = ["Q10", "Q100", "Q1000", "Q8", "Q1001", "Q98"]

你可以寫

arr.sort_by { |s| s[/\d+/].to_i }
  #=> ["Q8", "Q10", "Q98", "Q100", "Q1000", "Q1001"]

如果

s = "Q1000"

然后

s[/\d+/].to_i
  #=> 1000

請參閱Enumerable#sort_byString#[]

正則表達式/\\d+/匹配包含一個或多個數字的s子字符串。


如果數組是

arr = ["Q10b", "Q100", "Q1000", "Q10a", "Q1001", "Q98", "Q10c"]

你可以寫

arr.sort_by { |s| [s[/\d+/].to_i, s[/\D+\z/]] }
  #=> ["Q10a", "Q10b", "Q10c", "Q98", "Q100", "Q1000", "Q1001"] 

如果

s = "Q10b"

然后

[s[/\d+/].to_i, s[/\D+\z/]]
  #=> [10, "b"]

正則表達式/\\D+\\z/匹配s的子字符串,該子字符串在字符串的末尾 ( \\z ) 包含一個或多個非數字。

請參閱Array#<=> ,特別是第三段,了解排序時數組的排序方式。


如果數組是

arr = ["Q10b", "P100", "Q1000", "PQ10a", "Q1001", "Q98", "Q10c"]

你可以寫

arr.sort_by { |s| [s[/\A\D+/], s[/\d+/].to_i, s[/\D+\z/]] }
  #=> ["P100", "PQ10a", "Q10b", "Q10c", "Q98", "Q1000", "Q1001"]

如果

s = "PQ10a"

然后

[s[/\A\D+/], s[/\d+/].to_i, s[/\D+\z/]]
  #=> ["PQ", 10, "a"]

正則表達式/\\A\\D+/匹配s的子字符串,該子字符串在字符串的開頭 ( \\A ) 包含一個或多個非數字。

這應該對你有用,在排序之前將它們轉換為數字。

['100', '1000', '98', '10', '1001'].map(&:to_i).sort

這個奇怪的map(&:to_i)map { |x| x.to_i }簡寫map { |x| x.to_i }

編輯:

你可以用 AR 做到這一點。 如果列不包含偽裝成字符串的數字,這將引發錯誤。

Model.order("some_column::integer")

編輯二:

如果它也包含字符串,請嘗試此操作。

Model.order("cast(some_column as integer))"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM