/ / नेस्टेड हैश में आइटम को उनके मूल्यों द्वारा क्रमबद्ध करें - माणिक, छँटाई

एक नेस्टेड हैश में आइटम को उनके मूल्यों से क्रमबद्ध करें - रूबी, सॉर्टिंग

मुझे एक नेस्टेड हैश भेजा जा रहा है जिसे इसके मूल्यों द्वारा क्रमबद्ध करने की आवश्यकता है। उदाहरण के लिए।

@foo = {"a"=>{"z"=>5, "y"=>3, "x"=>88}, "b"=>{"a"=>2, "d"=>-5}}

जब निम्नलिखित चल रहा हो:

@foo["a"].sort{|a,b| a[1]<=>b[1]}

मुझे मिला:

[["y", 3], ["z", 5], ["x", 88]]

यह बहुत अच्छा है, यह वही है जो मैं चाहता हूं। समस्या यह है कि मैं हमेशा नहीं जानता कि सभी कुंजी क्या हैं जो मुझे भेजी जा रही हैं, इसलिए मुझे किसी प्रकार के लूप की आवश्यकता है। मैंने निम्नलिखित करने की कोशिश की:

@foo.each do |e|
e.sort{|a,b| a[1]<=>b[1]}
end

यह मेरे लिए समझ में आता है जब से मैं मैन्युअल रूप से @ foo.first [0] फोन करता हूं

"a"

और @ foo.first [1] रिटर्न

{"z"=>5, "y"=>3, "x"=>8}

लेकिन किसी कारण के लिए यह ठीक से छंटनी नहीं है(उदा। बिलकुल)। मुझे लगता है कि यह इसलिए है क्योंकि प्रत्येक "" "मानों के बजाय पूरे हैश ऑब्जेक्ट पर कॉल कर रहा है। मैं नेस्टेड हैश के मूल्यों को कैसे जाने बिना यह जानने के लिए कि यह क्या है?"

उत्तर:

उत्तर № 1 के लिए 6

आप इस तरह हैश पर लूप करना चाहते हैं:

@ foo.each करना | कुंजी, मूल्य | @foo [की] = value.sort {| ए, बी | [1] <=> b [१]} समाप्त

जवाब के लिए 4 № 2
@foo = {"a"=>{"z"=>5, "y"=>3, "x"=>88}, "b"=>{"a"=>2, "d"=>-5}}
@bar = Hash[ @foo.map{ |key,values| [ key, values.sort_by(&:last) ] } ]

या, कम मुश्किल रास्ते से:

@bar = {}
@foo.each do |key,values|
@bar[key] = values.sort_by{ |key,value| value }
end

दोनों मामलों में @bar यह बात निकलकर आना:

p @bar
#=> {
#=>   "a"=>[["y", 3], ["z", 5], ["x", 88]],
#=>   "b"=>[["d", -5], ["a", 2]]
#=> }

उत्तर № 3 के लिए 1

मेरा सहकर्मी थोड़ा और अधिक लचीले समाधान के साथ आया है जो किसी भी गहराई के एक सरणी को पुन: व्यवस्थित करेगा:

def deep_sort_by(&block)
Hash[self.map do |key, value|
[if key.respond_to? :deep_sort_by
key.deep_sort_by(&block)
else
key
end,

if value.respond_to? :deep_sort_by
value.deep_sort_by(&block)
else
value
end]

end.sort_by(&block)]
end

आप इसे सभी हैश में इंजेक्ट कर सकते हैं और फिर इसे इस तरह से कॉल कर सकते हैं:

myMap.deep_sort_by { |obj| obj }

कोड एक सरणी के लिए समान होगा। हम इसे एक रत्न के रूप में प्रकाशित किया दूसरों के उपयोग के लिए, देखें ब्लॉग पोस्ट अतिरिक्त विवरण के लिए।

अस्वीकरण: मैं इस कंपनी के लिए काम करता हूं।


जवाब के लिए 0 № 4

आपके उदाहरण में e एक अस्थायी सरणी है जिसमें [कुंजी, मान] जोड़ी होती है। इस मामले में, चरित्र कुंजी और नेस्टेड हैश। इसलिए e.sort{|a,b|...} चरित्र को हैश से तुलना करने का प्रयास करने जा रहा है, और एक रनटाइम त्रुटि के साथ विफल हो जाता है। मुझे लगता है कि आप शायद टाइप करने के लिए थे e[1].sort{...}। लेकिन यहां तक ​​कि यह सही ढंग से काम करने वाला नहीं है, क्योंकि आप कहीं भी हल किए गए हैश को स्टोर नहीं करते हैं: @foo.each मूल @foo लौटाता है और इसे अपरिवर्तित छोड़ देता है।

बेहतर उपाय है जो @Pan Thomakos द्वारा सुझाया गया है:

@foo.each do |key, value|
@foo[key] = value.sort{ |a,b| a[1]<=>b[1] }
end