2009-04-13 21 views
5

मैं एक हैश को सॉर्ट करना चाहता हूं जिसमें वास्तव में एक मूल्य के रूप में हैश है। उदाहरण के लिए:पर्ल में कुंजी द्वारा हैश के हैश को कैसे सॉर्ट कर सकता हूं?

my %hash1=(
    field1=>"", 
    field2=>"", 
    count=>0, 
); 
my %hash2; 
$hash2{"asd"}={%hash1}; 

और मैं %hash2 के विभिन्न गिनती मूल्यों के साथ %hash2 को हैश के बहुत सारे सम्मिलित किया गया।

के मूल्य मान के अनुसार मैं %hash1 को कैसे क्रमबद्ध कर सकता हूं?

क्या पर्ल के सॉर्ट फ़ंक्शन के साथ मैन्युअल रूप से क्विकॉर्ट को कार्यान्वित किए बिना ऐसा करने का कोई तरीका है?

+0

आप मतलब है कि आप हैश (hash1 की तरह) hash2 में मूल्यों से गिनती के अनुसार क्रमबद्ध की सूची प्राप्त करना चाहते हैं? – Jagmal

+0

हां जगमल का मतलब है कि मैं $ हैश 2 {"asd"} {count} के संबंध में सॉर्ट करना चाहता हूं। – systemsfault

उत्तर

10
my @hash1s = sort {$a->{count} <=> $b->{count}} values %hash2; 
+0

मैंने इस तरह से कोशिश की लेकिन निम्नलिखित चेतावनी प्राप्त करें: [चेतावनी]: – systemsfault

+0

पर संख्यात्मक तुलना (<=>) में अनियमित मूल्य का उपयोग, मेरे उत्तर के लिए कोड स्निपेट, और आपके उत्तर पर मेरी टिप्पणी के लिए, परीक्षण के दौरान मेरे लिए काम करें (यहां तक ​​कि "और सख्त उपयोग" के साथ)। –

+0

आपको वह चेतावनी मिल रही है क्योंकि आपके एक या अधिक हशों के पास 'गिनती' कुंजी के लिए कोई मूल्य नहीं है। यदि आप उन्हें 0 के रूप में गिनना चाहते हैं, तो आप {{$ a -> {count} || 0) <=> ($ b -> {count} || 0)} मान% हैश 2; – nohat

1

आप हैश (hash1 की तरह) hash2 में मूल्यों से गिनती के अनुसार क्रमबद्ध की सूची प्राप्त करना चाहते हैं, यह मदद मिल सकती है:

@sorted_hash1_list = sort sort_hash_by_count_key($a, $b) (values (%hash2); 


# This method can have any logic you want 
sub sort_hash_by_count_key { 
    my ($a, $b) = @_; 
    return $a->{count} <=> $b->{count}; 
} 
+0

क्या आपके पास वर्तमान में क्या है इसके बजाय "sort \ & sort_hash_by_count_key, मान% हैश 2" कहने का मतलब है? –

+0

मुझे लगता है कि यह इस तरह से काम करेगा, है ना? – Jagmal

0

बहुत के संदर्भ से कैसे तरह काम करता है के लिए http://perldoc.perl.org/functions/sort.html देखें पर्ल में

और यहां एक उदाहरण है .. पढ़ने योग्य होने की कोशिश कर रहा है, न कि परेशान।

#!/usr/bin/perl 
# Sort Hash of Hashes by sub-hash's element count. 
use warnings; 
use strict; 


my $hash= { 
      A=>{C=>"D",0=>"r",T=>"q"} 
      ,B=>{} 
      ,C=>{E=>"F",G=>"H"} 
      }; 

sub compareHashKeys {0+(keys %{$hash->{$a}}) <=> 0+(keys %{$hash->{$b}}) } 

my @SortedKeys = sort compareHashKeys keys %{$hash}; 
print join ("," , @SortedKeys) ."\n"; 
+0

के लिए '0+' क्या है? – systemsfault

+0

0+ मान को एक संख्यात्मक पर केंद्रित करना है, हालांकि, <=> पहले से ही ऐसा करता है, इसलिए 0+ वास्तव में अनावश्यक है। :-P –

+0

ठीक है, सीएमपी या <=> से बाहर आने वाला मान पहले से ही संख्यात्मक है, -1, 0, या 1 है। इससे कोई फर्क नहीं पड़ता कि डेटा क्या है। सॉर्ट() को चीजों को ऑर्डर करने का निर्णय लेने के लिए -1, 0, या 1 की आवश्यकता होती है। –

6

perlfaq4 से, "http://faq.perl.org/perlfaq4.html#How_do_I_sort_a_hash" का जवाब जानकारी आप एक साथ अपने कोड रखना होगा के सबसे है।

आप सीखना पर्ल में सॉर्टिंग पर अध्याय देखना भी चाहेंगे।

क्रिस का एक बिल्कुल अच्छा जवाब है, हालांकि मुझे values का उपयोग करने से नफरत है। एक ही बात करने के लिए एक और अधिक परिचित रास्ता शीर्ष स्तर के हैश की चाबी के माध्यम से लेकिन प्रकार दूसरे स्तर के प्रमुख द्वारा जाने के लिए है:

my @sorted_hashes = 
    sort { $hash2->{$a}{count} <=> $hash2->{$b}{count} } 
    keys %hash2; 

मैं इसे इस तरह से करना क्योंकि यह थोड़ा कम दिमाग झुकने ।


मैं हैश को कैसे क्रमबद्ध करूं (वैकल्पिक रूप से कुंजी के बजाय मूल्य से)?

(ब्रायन डी Foy के योगदान)

एक हैश क्रमबद्ध करने के लिए, कुंजी के साथ शुरू करते हैं। इस उदाहरण में, हम सॉर्ट फ़ंक्शन को कुंजियों की सूची देते हैं जो तब उन्हें ASCIIBetically तुलना करता है (जो आपकी लोकेल सेटिंग्स से प्रभावित हो सकता है)। आउटपुट सूची में ASCIIBetical ऑर्डर में कुंजी है। एक बार हमारे पास चाबियाँ हो जाने के बाद, हम उन रिपोर्टों को बनाने के लिए जा सकते हैं जो ASCIIBetical ऑर्डर में कुंजी सूचीबद्ध करते हैं।

my @keys = sort { $a cmp $b } keys %hash; 

foreach my $key (@keys) 
    { 
    printf "%-20s %6d\n", $key, $hash{$key}; 
    } 

हालांकि हम इस प्रकार() ब्लॉक में अधिक फैंसी प्राप्त कर सकते हैं। चाबियों की तुलना करने के बजाय, हम उनके साथ एक मूल्य की गणना कर सकते हैं और तुलना के रूप में उस मान का उपयोग कर सकते हैं।

उदाहरण के लिए, हमारे रिपोर्ट ऑर्डर केस-असंवेदनशील बनाने के लिए, हम सब कुछ लोअरकेस बनाने के लिए \ l अनुक्रम को डबल-उद्धृत स्ट्रिंग में उपयोग करते हैं। सॉर्ट() ब्लॉक तब निम्न निर्धारित मानों की तुलना करता है ताकि यह निर्धारित किया जा सके कि कुंजी को किस क्रम में रखा जाए।

my @keys = sort { "\L$a" cmp "\L$b" } keys %hash; 

नोट: यदि गणना महंगा है या हैश कई तत्व है, तो आप Schwartzian पर परिकलन परिणाम कैश करने के लिए रूपांतरण देखने के लिए चाहते हो सकता है।

यदि हम इसके बजाय हैश मान को सॉर्ट करना चाहते हैं, तो हम इसे देखने के लिए हैश कुंजी का उपयोग करते हैं। हम अभी भी चाबियों की एक सूची प्राप्त करते हैं, लेकिन इस बार उन्हें उनके मूल्य से आदेश दिया जाता है।

my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash; 

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

my @keys = sort { 
    $hash{$a} <=> $hash{$b} 
     or 
    "\L$a" cmp "\L$b" 
    } keys %hash; 
+0

वाह महान स्पष्टीकरण thanx। – systemsfault

0

संख्यात्मक उपयोग < => और स्ट्रिंग उपयोग cmp के लिए क्रमबद्ध करने के लिए।

# sort by the numeric count field on inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'count'} <=> $hash2{$b}->{'count'}} keys %hash2) { 
    print $key,$hash2{$key}->{'count'},"\n"; 
} 

# sort by the string field1 (or field2) on the inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'field1'} cmp $hash2{$b}->{'field1'}} keys %hash2) { 
    print $key,$hash2{$key}->{'field1'},"\n"; 
} 

उल्टा करने के लिए आदेश बस $ एक और $ ख स्वैप:

# sort by the numeric count field on inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'count'} <=> $hash2{$b}->{'count'}} keys %hash2) { 
    print $key,$hash2{$key}->{'count'},"\n"; 
} 

# sort by the string field1 (or field2) on the inner hash 
# 
foreach my $key (sort {$hash2{$a}->{'field1'} cmp $hash2{$b}->{'field1'}} keys %hash2) { 
    print $key,$hash2{$key}->{'field1'},"\n"; 
} 
संबंधित मुद्दे