2016-01-15 6 views
9

मैं एक सरणी को तारों और तारों के मिश्रण के साथ सॉर्ट करने की कोशिश कर रहा हूं। उदाहरण के लिए ले लो:चींटियों और तारों की सरणी को कैसे क्रमबद्ध करें?

a = ["a", "b", 5, "c", 4, "d", "a1", "a12", 3, 13, 2, "13a", "12a"] 

मैंने कोशिश की:

a.sort do |x, y| 
    if x.class == y.class 
    x <=> y 
    else 
    x.class.to_s <=> y.class.to_s 
    end 
end 

कौन देता है:

[2, 3, 4, 5, 13, "12a", "13a", "a", "a1", "a12", "b", "c", "d"] 

परिणाम मैं चाहता है:

[2, 3, 4, 5, "12a", 13, "13a", "a", "a1", "a12", "b", "c", "d"] 
+0

क्या आपके तारों में एक से अधिक संख्या हो सकती है, उदाहरण के लिए '" A1B2C3 "'? – Stefan

+0

क्या सही है? '[" ए 1 "," ए 12 "," ए 2 "]' या '[" ए 1 "," ए 2 "," ए 12 "]'? – Stefan

+0

@Stefan एक स्ट्रिंग में एक से अधिक संख्या होने की संभावना है। उत्तरार्द्ध '[" ए 1 "," ए 2 "," ए 12 "]' –

उत्तर

11
a.sort_by { |x| [(x.to_s.match(/^\d+/) ? x.to_i : 1.0/0), x.to_s] } 

विचार संख्यात्मक मूल्य से पहले क्रमबद्ध करना और दूसरा स्ट्रिंग मान द्वारा क्रमबद्ध करना है। यदि स्ट्रिंग संख्यात्मक मान से शुरू नहीं होती है, तो संख्यात्मक मान को अनंतता पर बलपूर्वक मानें।


संपादित: ओपी स्पष्ट किया के रूप में दिया है कि वह न सिर्फ प्रमुख संख्यात्मक मान पर विचार करना चाहता है, लेकिन वह सब का पालन करें, हम एक ही विचार उपयोग कर सकते हैं तो बस इस बार हम प्रत्येक व्यक्ति पर इसे लागू करने के लिए है स्ट्रिंग में संख्यात्मक और गैर-संख्यात्मक इकाई:

a.sort_by do |x| 
    x.to_s.split(/(\D+)/).map do |y| 
    [(y.match(/\d/) ? y.to_i : 1.0/0), y] 
    end 
end 
+1

सरणी में एक '0'' 13a "' और '" ए "' – Stefan

+0

@Stefan के बीच समाप्त होगा। – ndn

+0

यह बेहतर है, लेकिन यह '["a13", "a2"]' ठीक से सॉर्ट नहीं करता है। – Stefan

संबंधित मुद्दे