2009-06-16 10 views
42

मेरे पास एक पर्ल स्क्रिप्ट है जो टेक्स्ट फ़ाइल में विभिन्न तारों की घटनाओं की संख्या की गणना कर रही है। मैं यह जांचने में सक्षम होना चाहता हूं कि एक निश्चित स्ट्रिंग हैश में अभी तक एक कुंजी नहीं है। क्या यह पूरी तरह से करने का एक बेहतर तरीका है?मैं कैसे देख सकता हूं कि एक पर्ल हैश के पास पहले से ही एक निश्चित कुंजी है या नहीं?

यहाँ मैं क्या कर रहा हूँ है:

foreach $line (@lines){ 
    if(($line =~ m|my regex|)) 
    { 
     $string = $1; 
     if ($string is not a key in %strings) # "strings" is an associative array 
     { 
      $strings{$string} = 1; 
     } 
     else 
     { 
      $n = ($strings{$string}); 
      $strings{$string} = $n +1; 
     } 
    } 
} 
+4

सवाल यह है कि आप इसके साथ परेशान क्यों हो रहे हैं? यदि यह अस्तित्व में नहीं है तो $ n अनिश्चित होगा। Undef का संख्यात्मक मान 0 है, इसलिए $ n + 1 = 1। यह जांचने की कोई आवश्यकता नहीं है कि हैश में शुरुआत हो रही है या नहीं। –

उत्तर

95

मैं एक महत्वपूर्ण एक हैश में मौजूद रहने पर जाँच करने के लिए लगता है कि आप सिर्फ

if (exists $strings{$string}) { 
    ... 
} else { 
    ... 
} 
+13

ध्यान रखें कि पर्ल किसी भी मध्यवर्ती कुंजी को स्वचालित रूप से सक्रिय करेगा जो कि "चेक" करने के लिए एक बहुआयामी हैश में मौजूद नहीं है, यदि आपकी आखिरी हैश में मौजूद कुंजी मौजूद है। यह इस उदाहरण की तरह एक साधारण हैश के साथ कोई समस्या नहीं है .. .. मेरा% test =(); प्रिंट "बार" अगर ($ test {'foo'} {'bar'} मौजूद है); # perl बस प्रिंट को देखने के लिए foo कुंजी को स्वतः सक्रिय किया गया "प्रिंट अब मौजूद है और आपने इसकी अपेक्षा नहीं की हो सकती है!" अगर ($ test {'foo'} मौजूद है); – Drew

6

मुझे लगता है कि इस कोड आपके प्रश्न का उत्तर चाहिए:

use strict; 
use warnings; 

my @keys = qw/one two three two/; 
my %hash; 
for my $key (@keys) 
{ 
    $hash{$key}++; 
} 

for my $key (keys %hash) 
{ 
    print "$key: ", $hash{$key}, "\n"; 
} 

आउटपुट:

three: 1 
one: 1 
two: 2 

यात्रा करने के लिए सरल किया जा सकता है:

$hash{$_}++ for (@keys); 

($_ देखें perlvar में।) और तुम भी कुछ इस तरह लिख सकते हैं:

$hash{$_}++ or print "Found new value: $_.\n" for (@keys); 

कौन सा प्रत्येक कुंजी पहली बार यह खबर दी है मिल गया।

+0

हाँ, बात यह है कि मैं समय से पहले नहीं जानता कि चाबियाँ क्या होंगी। –

+1

हां, आपको इस उद्देश्य के लिए कुंजी की उपस्थिति की जांच करने की आवश्यकता नहीं है। आप बस $ स्ट्रिंग्स {$ 1} ++ कह सकते हैं। यदि कुंजी वहां नहीं है, तो इसे मूल्य के रूप में अपरिफ के साथ जोड़ा जाएगा, जो ++ आपके लिए 0 के रूप में व्याख्या करेगा। – Arkadiy

+0

निश्चित रूप से। मुद्दा यह है कि आप $ चक्र {$ 1} ++ के साथ अपने चक्र (यदि के तहत) के पूरे शरीर को प्रतिस्थापित कर सकते हैं। – zoul

-1

तुम बस के साथ जा सकते हैं:

if(!$strings{$string}) .... 
+0

हाँ जो भी काम करता है। धन्यवाद! –

+7

यह केवल तभी काम करता है जब सभी चाबियों में ऐसे मान होते हैं जो झूठी नहीं हैं। आम तौर पर, यह एक बुरा धारणा है। उपयोग करें(), जो विशेष रूप से इसके लिए डिज़ाइन किया गया है। –

+2

@brian de foy - आह हे। मुझे पता था कि मुझे जवाब नहीं देना चाहिए था :-) –

9

ठीक है, अपने पूरे कोड के लिए सीमित किया जा सकता है:

foreach $line (@lines){ 
     $strings{$1}++ if $line =~ m|my regex|; 
} 

यदि मान वहाँ नहीं है, ++ ऑपरेटर यह समझेंगे 0 होने के लिए (और फिर 1 तक बढ़ोतरी)। यदि यह पहले से ही है - यह केवल वृद्धि होगी।

+0

जबकि आपका उत्तर सत्य है, यह हैश के बारे में प्रश्न का उत्तर देता है। – Chris

9

मैं if ($hash{$key}) का उपयोग करने के खिलाफ सलाह दूंगा क्योंकि यह कुंजी नहीं है, लेकिन यह मान शून्य या खाली है, तो आप ऐसा नहीं करेंगे।

+1

उन कुछ परिस्थितियों में केवल नेस्टेड कुंजी के लिए हैं। इस समस्या के लिए, उत्तर मौजूद है। एक शॉट में नेस्टेड कुंजी के लिए मौजूद नहीं है। –

+1

डाउनवोट अभी भी थोड़ा कठोर है - चेतावनी इस प्रश्न में लिपि की सादगी से अमान्य नहीं है। अधिक महत्वपूर्ण बात यह है कि अगर ($ हैश {$ कुंजी}) का उपयोग करने का मुद्दा न तो परिभाषित और न ही मौजूद है: "शून्य लेकिन सत्य" समस्या। – RET

+0

"शून्य लेकिन सही" चीज़ एक अपवर्तनीय हकदार है। लेकिन आपने ऑटोविविफिकेशन के बारे में जो कहा वह बस गलत है और एक डाउनवोट का हकदार है। – innaM

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

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