2009-12-23 96 views
6

我想先按字符串對數組進行排序,然後再對數字進行排序。我該怎麼做呢?在Ruby中對字符串和數字進行排序

+1

你的問題是不是真的不夠具體。你想要分類什麼?字符串或字符?你的意思是你總是希望字母排序低於數字?如果一個字符串有混合字母和數字會怎麼樣?或者你是否想要在字母排序之前對字母進行排序? – 2009-12-23 22:30:50

+0

你能否澄清你的問題?也許給你想要的排序順序的例子? – 2009-12-23 22:32:54

+0

陣列中有什麼? – klochner 2009-12-23 23:05:45

回答

15

用於解決棘手各種各樣的一般技巧是使用#sort_by,與塊返回具有初級和次級的排序順序的陣列(和,如果需要它,叔胺等)

a = ['foo', 'bar', '1', '2', '10'] 
b = a.sort_by do |s| 
    if s =~ /^\d+$/ 
    [2, $&.to_i] 
    else 
    [1, s] 
    end 
end 
p b # => ["bar", "foo", "1", "2", "10"] 

這是因爲數組比較由Ruby定義的方式。該比較由Array#<=>方法定義:

以「按元素」的方式比較陣列; ary的第一個元素與other_ary中的第一個元素使用< =>運算符進行比較,然後每個第二個元素等等。只要任何這樣的比較的結果是非零的(即兩個相應的元素不相等),那麼返回整個數組比較的結果。

+0

如何處理Float對象?它正在打破,當集合包含'浮動'..我基本上使用您的代碼,但它正在打破'浮動'對象.. – 2015-02-06 16:10:44

17

先將數字和字符串排序,然後按順序放置數字和字符串,然後依次放置字符串,然後按順序排列。

>> a = [1, 2, "b", "a"] 

>> a.partition{|x| x.is_a? String}.map(&:sort).flatten 
=> ["a", "b", 1, 2] 
+0

對,謝謝你的回答, – s84 2009-12-23 23:17:05

+0

我希望我去睡覺。實際上,數組只是字符串,但字符串可能以字母的「數字」開始 – s84 2009-12-23 23:33:06

+5

使用「分區...扁平化」組合非常棒。 – akuhn 2009-12-23 23:58:57

2

通常情況下,alphabetization首先用數字完成。如果你想按字母順序排列數字前的字母,你需要改變使用的比較函數。

# I realize this function could be done with less if-then-else logic, 
# but I thought this would be clearer for teaching purposes. 
def String.mysort(other) 
    length = (self.length < other.length) ? self.length : other.length 
    0.upto(length-1) do |i| 
    # normally we would just return the result of self[i] <=> other[i]. But 
    # you need a custom sorting function. 
    if self[i] == other[i] 
     continue # characters the same, skip to next character. 
    else 
     if self[i] ~= /[0-9]/ 
     if other[i] ~= /[0-9]/ 
      return self[i] <=> other[i] # both numeric, sort normally. 
     else 
      return 1 # self is numeric, other is not, so self is sorted after. 
     end 
     elsif other[i] ~= /[0-9]/ 
     return -1 # self is not numeric, other is, so self is sorted before. 
     else 
     return self[i] <=> other[i] # both non-numeric, sort normally. 
     end 
    end 
    end 

    # if we got this far, the segments were identical. However, they may 
    # not be the same length. Short sorted before long. 
    return self.length <=> other.length 
end 

['0','b','1','a'].sort{|x,y| x.mysort(y) } # => ['a', 'b', '0', '1'] 
0

如果你正在試圖理清混合大小寫和數字,只有少數人在地球上能做到這一點的專有應用程序之外。這是一個吸盤的祕密。你必須使用一個qsort,這使得排序很容易,直到你混合案件(大寫和小寫字母)。然後大學,書籍和互聯網離開你掛。這種黑客的價值體現在黃金上,並且是所有原因的編程黃銅戒指。

要用數字對數字進行排序,您必須將數字轉換爲字符串。你必須使用大寫字母來推斷。如果你的單詞「Ant」,「ant」和「anT」越少,它們應該都指向大寫排序列表中的單詞「ANT」。然後,您將創建一個只包含這三個單詞[「螞蟻」,「螞蟻」和「anT」]的列表(數組),並使用qsort作爲聯繫斷路器對它們進行排序。

然後,您將它們插入到最終的排序數組中。設計相當困難。 「A」在ascii上是65,'a'是97,在'Z'和'a'之間有很多垃圾字符!這不是偶然的!這是我告訴你的陰謀!

可以創建一個排序表越三立羣的文字等:

A,A,B,B,C,C,d,d,E,E,F,F,G,G, H,h,I,i,J,j,K,k,L,l,M,m,N,n,... 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 ...

圍繞此塊建立表格,以「」(空格)ascii 32到128開始。您可能想要按順序重新排列數字,A 65是隻有例子。

這使得它更容易,但很可能會導致大多數編程語言的宏之外的性能下降。祝你好運!

1

這裏有一些詳細的答案。將數組分成兩個子數組:字符串和數字,對它們進行排序和連接。

array = [1, 'b', 'a', 'c', 'd', 2, 4, 3] 
strings = [] 
numbers = [] 
array.each do |element| 
    if element.is_a? String 
    strings << element 
    else 
    numbers << element 
    end 
end 
sorted_array = strings.sort + numbers.sort 
sorted_array # ['a', 'b', 'c', 'd', 1, 2, 3, 4] 
2
a = ['1', '10', '100', '2', '42', 'hello', 'x1', 'x20', 'x100', '42x', '42y', '10.1.2', '10.10.2', '10.8.2'] 
a.map {|i| i.gsub(/\d+/) {|s| "%08d" % s.to_i } }.zip(a).sort.map{|x,y| y} 
# => ["1", "2", "10", "10.1.2", "10.8.2", "10.10.2", "42", "42x", "42y", "100", "hello", "x1", "x20", "x100"] 
+1

a.sort_by {| i | i.gsub(/ \ d + /) {| S | 「%08d」%s.to_i}} – bluexuemei 2015-04-30 00:00:54

+0

@bluexuemei啊挺漂亮的。涼 – neoneye 2015-05-04 07:05:44

相關問題