2009-12-23 6 views
6

में तारों और संख्याओं को क्रमबद्ध करें मैं पहले स्ट्रिंग्स और फिर संख्याओं द्वारा एक सरणी सॉर्ट करना चाहता हूं। मैं यह कैसे करु?रूबी

+1

आपका प्रश्न काफी वास्तव में विशिष्ट नहीं है। आप क्या क्रमबद्ध करने की कोशिश कर रहे हैं? स्ट्रिंग्स, या अक्षर? और क्या आपका मतलब है कि आप हमेशा संख्याओं से कम क्रमबद्ध करने के लिए अक्षर चाहते हैं? क्या होगा यदि एक स्ट्रिंग मिश्रित अक्षरों और संख्या है? या क्या आप लेक्सिकोग्राफिक सॉर्ट चाहते हैं जिसमें अक्षरों को संख्याओं से पहले क्रमबद्ध किया गया हो? –

+0

क्या आप कृपया अपने प्रश्न को स्पष्ट कर सकते हैं? शायद आप जिस सॉर्ट ऑर्डर चाहते हैं उसका उदाहरण दें? –

+0

सरणी में क्या है? – klochner

उत्तर

15

मुश्किल प्रकार हल करने के लिए एक सामान्य चाल एक सरणी प्राथमिक और माध्यमिक सॉर्ट क्रम होने लौट (और, आप इसे की आवश्यकता है, तृतीयक, आदि)

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"] 

ब्लॉक के साथ, #sort_by उपयोग करने के लिए है यह रूबी द्वारा सरणी तुलना परिभाषित करने के तरीके के कारण काम करता है। तुलना Array#<=> विधि द्वारा परिभाषित की गई है:

Arrays की तुलना "तत्व-वार" तरीके से की जाती है; आर्य का पहला तत्व < => ऑपरेटर, फिर प्रत्येक तत्व, आदि का उपयोग करके अन्य_री के पहले तत्व के साथ तुलना की जाती है ... जैसे ही ऐसी किसी भी तुलना का नतीजा शून्य होता है (यानी दो संबंधित तत्व बराबर नहीं होते हैं), परिणाम पूरे सरणी तुलना के लिए वापस आ गया है।

+0

'फ़्लोट' ऑब्जेक्ट्स कब संभालें? यह तोड़ रहा है, जब संग्रह में 'फ्लोट' है .. मैं मूल रूप से आपके कोड का उपयोग कर रहा हूं, लेकिन यह 'फ्लोट' ऑब्जेक्ट्स के लिए तोड़ रहा है .. –

17

संख्याओं को पहले रखकर मिश्रित संख्याओं और तारों की एक सरणी को क्रमबद्ध करें, और क्रमशः, स्ट्रिंग्स दूसरे के बाद, और क्रम में।

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

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

सही है, उत्तर के लिए धन्यवाद, – s84

+0

मेरी इच्छा है कि मैं बिस्तर पर जाऊं। असल में, सरणी केवल तार है, लेकिन तार – s84

+5

'विभाजन ... flatten' combo के बहुत बढ़िया उपयोग के "संख्या" से शुरू हो सकते हैं। – akuhn

2

आम तौर पर, वर्णमाला पहले संख्याओं के साथ की जाती है। यदि आप संख्याओं से पहले वर्णमाला वर्णित कुछ वर्णमाला बनाना चाहते हैं, तो आपको उपयोग किए गए तुलना फ़ंक्शन को बदलने की आवश्यकता होगी।

# 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 का उपयोग करना चाहिए जो सॉर्टिंग को तब तक आसान बनाता है जब तक आप मामलों को मिश्रण न करें (ऊपरी और निचले केस अक्षरों)। फिर कॉलेज, किताबें और इंटरनेट आपको फांसी छोड़ देते हैं। यह हैक सोने में अपना वजन लायक है और सभी कारणों से प्रोग्रामिंग की पीतल की अंगूठी है।

शब्दों के साथ संख्याओं को क्रमबद्ध करने के लिए आपको संख्याओं को स्ट्रिंग में परिवर्तित करना होगा। आपको ऊपरी मामले का उपयोग करना चाहिए। यदि आपके पास "चींटी", "चींटी" और "एटीटी" शब्द कम हैं, तो उन्हें ऊपरी केस सॉर्ट सूची में "एएनटी" शब्द को इंगित करना चाहिए। इसके बाद आप इन तीन शब्दों ["चींटी", "चींटी" और "एएनटी"] की एक सूची (सरणी) तैयार करेंगे और उन्हें सॉर्ट करने के लिए टाई ब्रेकर के रूप में qsort का उपयोग करेंगे।

फिर आप उन्हें अंतिम सॉर्टिंग सरणी में डालें। यह डिजाइन द्वारा काफी मुश्किल है। "ए" एएससीआई पर 65 है और 'ए' 9 7 है जिसमें 'ज़ेड' और 'ए' के ​​बीच बहुत सारे कचरे के पात्र हैं! यह कोई दुर्घटना नहीं है! यह एक षड्यंत्र है जो मैं आपको बताता हूं!

आप एक छँटाई तालिका बना सकते हैं और अधिक sanely समूहों जैसे पात्रों:

ए, ए, बी, बी, सी, सी, डी, डी, ई, ई, एफ, एफ, जी, जी, एच, एच, आई, आई, जे, जे, के, के, एल, एल, एम, एम, एन, एन, ... 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 ...

इस ब्लॉक के आस-पास की तालिका को "स्पेस" एसीआईआई 32 से 128 तक शुरू करने के लिए। "शायद आप क्रमशः संख्या 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 + /) {| है | "% 08d"% s.to_i}} – bluexuemei

+0

@bluexuemei आह जो बहुत साफ है। ठंडा – neoneye