2009-10-13 13 views
19

निम्नलिखित प्रोग्राम में हैश का उपयोग करके इसकी घटना की गणना करने के बाद मैं वास्तविक सूची के क्रम को कैसे बनाए रख सकता हूं? उदाहरण के लिए, <DATA>मैं पर्ल हैश में जोड़ने वाली कुंजियों के क्रम को कैसे बनाए रख सकता हूं?

a 
b 
e 
a 
c 
d 
a 
c 
d 
b 
etc. 

हैश का उपयोग करना, मैं प्रत्येक तत्व की घटना की गिनती कर रहे हैं।

और क्या मैं चाहता है:

a 3 
b 2 
e 1 
c 2 
d 2 

लेकिन निम्नलिखित कार्यक्रम मुझे कुछ और दर्शाता है। एक हैश तालिका में

my (%count, $line, @array_1, @array_2); 
while ($line = <DATA>) { 
    $count{$line}++ if ($line =~ /\S/); 
} 
@array_1 = keys(%count); 
@array_2 = values(%count); 
for(my $i=0; $i<$#array_1; $i++) 
{ 
    print "$array_1[$i]\t $array_2[$i]"; 
} 
+0

क्या आप इसे आसानी से पढ़ने के लिए अपने कोड को टैग कर सकते हैं। – Space

+0

तो, आपने पांच प्रश्न पूछे हैं, उन सभी के जवाबों का एक समूह प्राप्त हुआ है और उनमें से कोई भी स्वीकार करने के लिए पर्याप्त नहीं है, है ना? –

+0

@ शिनान: नहीं ... यह नहीं है ...... मैं सभी अद्भुत उत्तरों को स्वीकार करने के लिए जगह नहीं ढूंढ सका .... बस सोच रहा हूं कि यह एक टिप्पणी जोड़कर किया जाता है या कोई अन्य जगह है .... stackoverflow के साथ-साथ perl के लिए एक नौसिखिया ... क्षमा करें, मुझे इस मंच में सक्रिय रूप से भाग लेने के तरीके सीखने के लिए कुछ समय लेना चाहिए ... लगभग सभी उत्तरों ने मुझे सीखने के लिए एक नया विचार दिया ... और मेरे उद्देश्यों की सेवा की ... – Cthar

उत्तर

13

डाटा कुंजी 'हैश कोड है, जो सबसे प्रयोजनों के लिए एक यादृच्छिक क्रम की तरह है के क्रम में संग्रहित है। आप प्रत्येक कुंजी की पहली उपस्थिति के क्रम को भी स्टोर करना चाहते हैं। Tie::IxHash

use Tie::IxHash; 
my %count; 
tie %count, 'Tie::IxHash'; 

while ($line = <DATA>) { 
$count{$line}++ if ($line =~ /\S/); 
} 

while(my($key, $value)= each %count) { 
    print "$key\t $value"; 
} 
+3

IMHO यह टाई :: IxHash का उपयोग करने से बेहतर समाधान है, जो मुझे लगता है कि ओपी की मूल जरूरतों से परे है। चाबियों के प्रदर्शन क्रम का उपयोग करने के लिए यह अधिक उपयुक्त है, जैसा कि इस उत्तर में है, या 'मेरी $ कुंजी का पूर्वानुमान (सॉर्ट कुंजी% गणना) {...} ' – Ether

30

Hashes आदेश दिया नहीं कर रहे हैं, लेकिन हमेशा की तरह, CPAN एक समाधान प्रदान करता है:

my (%count, @order); 
while(<DATA>) { 
    chomp; 
    push @order, $_ unless $count{$_}++; 
} 
print "$_ $count{$_}\n" for @order; 
__DATA__ 
a 
b 
e 
a 
c 
d 
a 
c 
d 
b 
5

सीधे शब्दों में:

my (%count, $line, @display_order); 
while ($line = <DATA>) { 
    chomp $line;   # strip the \n off the end of $line 
    if ($line =~ /\S/) { 
     if ($count{$line}++ == 0) { 
      # this is the first time we have seen the key "$line" 
      push @display_order, $line; 
     } 
    } 
} 

# now @display_order holds the keys of %count, in the order of first appearance 
foreach my $key (@display_order) 
{ 
    print "$key\t $count{$key}\n"; 
} 
9

perlfaq4 के से यहां एक तरह से इस समस्या से संपर्क करना है "How can I make my hash remember the order I put elements into it?"


का उत्तर

मैं अपने हैश को उस ऑर्डर को कैसे याद कर सकता हूं जिसमें मैंने तत्व डाले हैं?

सीपीएएन से टाई :: IxHash का उपयोग करें।

use Tie::IxHash; 

tie my %myhash, 'Tie::IxHash'; 

for (my $i=0; $i<20; $i++) { 
    $myhash{$i} = 2*$i; 
    } 

my @keys = keys %myhash; 
# @keys = (0,1,2,3,...) 
3

मुझे विश्वास नहीं है कि यह हमेशा एक बेहतर तकनीक है, लेकिन मैंने इसे कभी-कभी उपयोग किया है। हैश के "देखा" प्रकार के बजाय, यह गिनती और ऑर्डर दोनों को संग्रहीत कर सकता है।

असल में, $count{$line} की बजाय, $count{$line}{count} बार देखा गया समय और $count{$line}{order} वह क्रम है जिसे देखा गया था।

my %count; 
while (my $line = <DATA>) { 
    chomp $line; 
    if ($line =~ /\S/) { 
     $count{$line} ||= { order => scalar(keys(%count)) }; 
     $count{$line}{count}++; 
    } 
} 

for my $line (sort { $count{$a}{order} <=> $count{$b}{order} } keys %count) { 
    print "$line $count{$line}{count}\n"; 
} 
4

एक अन्य विकल्प डेविड गोल्डन की (@xdg) सरल शुद्ध पर्ल Hash::Ordered मॉड्यूल है। आप ऑर्डर प्राप्त करते हैं लेकिन यह धीमा है क्योंकि हैश दृश्यों के पीछे एक वस्तु बन जाता है और आप हैश तत्वों तक पहुंचने और संशोधित करने के तरीकों का उपयोग करते हैं।

शायद ऐसे मानक हैं जो मॉड्यूल को नियमित हैश की तुलना में धीमा कर सकते हैं, लेकिन छोटे स्क्रिप्ट में कुंजी/मूल्य डेटा संरचनाओं के साथ काम करने का एक अच्छा तरीका है और इस तरह के आवेदन में मेरे लिए पर्याप्त तेज़ है। दस्तावेज़ में हैश को ऑर्डर करने के लिए कई अन्य दृष्टिकोण भी शामिल हैं।

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