संख्या मान के आधार पर रूबी हैश को कैसे सॉर्ट करें?


154

मेरे पास एक काउंटर हैश है जिसे मैं गिनती द्वारा क्रमबद्ध करने की कोशिश कर रहा हूं। मैं जिस समस्या को चला रहा हूं, वह यह है कि डिफ़ॉल्ट Hash.sort फ़ंक्शन संख्याओं के बजाय स्ट्रिंग्स जैसी संख्याओं को क्रमबद्ध करता है।

अर्थात हश:

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }

इस कोड को चलाना:

metrics.sort {|a1,a2| a2[1]<=>a1[1]}

एक क्रमबद्ध सरणी लौटाएगा:

[ 'siteb.com', 9, 'sitea.com', 745, 'sitec.com', 10]

भले ही 745 9 से बड़ी संख्या है, 9 सूची में पहले दिखाई देगा। जब यह दिखाने की कोशिश की जा रही है कि शीर्ष की गिनती किसके पास है, तो यह मेरे जीवन को कठिन बना रहा है। :)

संख्या मान आकार द्वारा हैश (या एक सरणी भी) को कैसे सॉर्ट करना है पर कोई विचार?

मैं किसी भी मदद की सराहना करता हूं।


आप किस माणिक संस्करण का उपयोग करते हैं? आपका सॉर्ट परिणाम बहुत अजीब है
fl00r

जवाबों:


268

कोई विचार नहीं है कि आपको अपने परिणाम कैसे मिले, क्योंकि यह स्ट्रिंग मान द्वारा सॉर्ट नहीं करेगा ... आपको रिवर्स a1और a2आपके उदाहरण में होना चाहिए

किसी भी मामले में (म्लादेन के अनुसार) सबसे अच्छा तरीका है:

metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" => 10 }
metrics.sort_by {|_key, value| value}
  # ==> [["siteb.com", 9], ["sitec.com", 10], ["sitea.com", 745]]

यदि आपको एक हैश की आवश्यकता है, तो आप उपयोग कर सकते हैं to_h(रूबी 2.0+ में)

metrics.sort_by {|_key, value| value}.to_h
  # ==> {"siteb.com" => 9, "sitec.com" => 10, "sitea.com", 745}

84
या बसsort_by{|k,v| v}
Mladen Jablanović

मेरा नंबर एक स्ट्रिंग के रूप में वापस आ रहा था, जिसने इसे तय किया .. मेरे पास उस क्रम में a2 और a1 था क्योंकि मैं चाहता था कि परिणाम छंटनी चाहिए .. हालांकि आपकी प्रतिक्रिया के लिए धन्यवाद।
डस्टिन एम।

यही कारण है कि मैं रूबी से प्यार करता हूं ... ऐसी समस्या अन्य भाषाओं में सिर में दर्द है। इतना सरल
Hady Elsahar

18
@ एलचीन: आप उपयोग कर सकते हैंmetrics.sort_by{ |k, v| v }.reverse.to_h
मार्क-एंड्रे लाफ्यून जून

4
वास्तव में और भी सरल: hash.sort_by (&: last) एक ही कैवेट के साथ जोड़े बनाम हैश की एक सरणी प्राप्त करने के बारे में।
गेरी ग्लीसन

84

चूंकि मूल्य अंतिम प्रविष्टि है, आप यह कर सकते हैं:

metrics.sort_by(&:last)

4
यह कमाल का है! की पूर्व परिभाषा के लिए कोई संदर्भ &:last?
ताम्र शालाश


14

पहले से ही जवाब दिया लेकिन अभी भी। अपना कोड बदलें:

metrics.sort {|a1,a2| a2[1].to_i <=> a1[1].to_i }

रास्ते में तार के लिए परिवर्तित या नहीं, यह काम करेगा।


9

यह वह व्यवहार नहीं है जिसे मैं देख रहा हूं:

irb(main):001:0> metrics = {"sitea.com" => 745, "siteb.com" => 9, "sitec.com" =>
 10 }
=> {"siteb.com"=>9, "sitec.com"=>10, "sitea.com"=>745}
irb(main):002:0> metrics.sort {|a1,a2| a2[1]<=>a1[1]}
=> [["sitea.com", 745], ["sitec.com", 10], ["siteb.com", 9]]

क्या यह संभव है कि रेखा के साथ कहीं आपके नंबर को तार में परिवर्तित किया जा रहा है? क्या कोई और कोड है जिसे आप पोस्ट नहीं कर रहे हैं?


अहह आपका अधिकार ऐसा लग रहा है जैसे मेरे कोड में परिणाम एक स्ट्रिंग के रूप में वापस आ रहा था। पेस्की डेटा प्रकार। :) कभी-कभी मैं समस्या के बहुत करीब हूं। धन्यवाद।
डस्टिन एम।

1
हाँ। कभी-कभी मैं किसी को रूबी को "अनकैप्ड" के रूप में सुनता हूं। ओह, नहीं, यह निश्चित रूप से टाइप किया गया है। यह सिर्फ सांख्यिकीय रूप से टाइप नहीं किया गया है। :)
जैकब मैटिसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.