2012-01-20 17 views
7

कार्य: नक्शा का उपयोग करके हैश बनाने के लिए, जहां कुंजी दिए गए सरणी @ ए के तत्व हैं, और मान पहले कुछ फ़ंक्शन f द्वारा लौटाई गई सूची के तत्व हैं ($ element_of_a):पर्ल: सूचियों के लिए पहला तत्व

my @a = (1, 2, 3); 
my %h = map {$_ => (f($_))[0]} @a; 

च जब तक सभी ठीक() एक खाली सूची देता है (कि च (के लिए बिल्कुल सही है), और उस मामले में मैं undef आवंटित करने के लिए) चाहते हैं। त्रुटि निम्न कोड के साथ reproduced किया जा सकता है:

my %h = map {$_ =>()[0]} @a; 

त्रुटि की तरह ही "हैश काम में तत्वों की विषम संख्या" लग रहा है। जब मैं कोड को फिर से लिखने ऐसी है कि:

my @a = (1, 2, 3); 
my $s =()[0]; 
my %h = map {$_ => $s} @a; 

या

my @a = (1, 2, 3); 
my %h = map {$_ => undef} @a; 

पर्ल बिल्कुल शिकायत नहीं है।

तो मुझे इसे कैसे हल करना चाहिए - वापस लौटाई गई सूची के पहले तत्वों को प्राप्त करें(), जब लौटाई गई सूची खाली हो जाती है?

पर्ल संस्करण 5.12.3

धन्यवाद।

+3

लपेटें 'f' करने के लिए कॉल इतनी है कि जब यह एक खाली सूची देता है, आप की आपूर्ति' undef' या अन्यथा सूची लौटाया के पहले तत्व। –

उत्तर

7

मैंने अभी थोड़ा सा खेला है, और ऐसा लगता है कि ()[0], सूची संदर्भ में, undef स्केलर के बजाय खाली सूची के रूप में व्याख्या की गई है। उदाहरण के लिए, यह:

my @arr =()[0]; 
my $size = @arr; 
print "$size\n"; 

प्रिंट 0। तो $_ =>()[0] लगभग $_ के बराबर है।

इसे ठीक करने के लिए, आप अदिश संदर्भ के लिए मजबूर करने scalar फ़ंक्शन का उपयोग कर सकते हैं:

my %h = map {$_ => scalar((f($_))[0])} @a; 

या आप सूची के अंत में एक स्पष्ट undef संलग्न कर सकते हैं:

my %h = map {$_ => (f($_), undef)[0]} @a; 

या आप कर सकते हैं अपने फ़ंक्शन के रिटर्न वैल्यू को एक सच्चे सरणी में लपेटें (केवल एक फ्लैट सूची के बजाय):

my %h = map {$_ => [f($_)]->[0]} @a; 

(मुझे लगता है कि अंतिम विकल्प सबसे ज्यादा पसंद, व्यक्तिगत रूप से।)


एक खाली सूची का एक टुकड़ा की विशेष व्यवहार “Slices” in perldata के तहत दर्ज है:

एक खाली सूची का एक टुकड़ा अभी भी एक है खाली सूची[...] इससे छोरों को समाप्त कि जब एक अशक्त सूची लौटा दिया जाता है लिखने के लिए बनाता है:

while (($home, $user) = (getpwent)[7,0]) { 
    printf "%-8s %s\n", $user, $home; 
} 
+1

मैंने प्रलेखन में एक उद्धरण में संपादित किया है जो बताता है कि '() [0] 'अनावश्यक के बजाय खाली सूची क्यों देता है। अगर आप स्वीकृति नहीं देते हैं, तो कृपया मेरे संपादन को वापस करने के लिए स्वतंत्र महसूस करें (या बेहतर अभी तक, इसे बेहतर बनाएं)। – derobert

+0

@derobert: I * दृढ़ता से * स्वीकृति दें। आपका बहुत बहुत धन्यवाद! – ruakh

+0

यहां विश्लेषण के साथ कुछ भी गलत नहीं है, लेकिन यह बहुत सी शोर है। मैं व्यक्तिगत रूप से किनारे के मामले को 'एफ' संभालना पसंद करता हूं क्योंकि यह कोड को इस तरह से अधिक बनाए रखने योग्य बनाता है। बेशक, यदि 'f' की परिभाषा पर कोई नियंत्रण नहीं है, तो यह एक अलग मामला है – Zaid

0

मैं दूसरे जोनाथन Leffler के सुझाव - करने के लिए सबसे अच्छी बात जड़ से समस्या का समाधान हो सकता है पर अगर सभी संभव:

sub f { 

    # ... process @result 

    return @result ? $result[0] : undef ; 
} 

स्पष्ट undef आवश्यक है के लिए खाली सूची समस्या उन्हें धोखा दिया जा करने के लिए।

0

सबसे पहले, सभी प्रतिलिपिओं के लिए बहुत धन्यवाद! अब मुझे लगता है कि मुझे वास्तविक कार्य के वास्तविक विवरण प्रदान करना चाहिए।

मैं एक XML तत्व प्रत्येक के सेट से युक्त फ़ाइल को पार्स कर रहा हूँ कि तरह लग रहा है:

('attr_1' => 'value_1', 
'attr_2' => 'value_2', 
'attr_3' => undef) 
:

<element> 
    <attr_1>value_1</attr_1> 
    <attr_2>value_2</attr_2> 
    <attr_3></attr_3> 
</element> 

मेरा लक्ष्य तत्व है जो निम्न कुंजी और मूल्यों में शामिल है के लिए पर्ल हैश बनाने के लिए है

चलिए <attr_1> तत्व पर नज़र डालें। XML::DOM::ParserCPAN मॉड्यूल जो मैं पार्सिंग के लिए उपयोग करता हूं, उनके लिए क्लास XML::DOM::Element का ऑब्जेक्ट बनाता है, आइए उनके संदर्भ के लिए $attr नाम दें। तत्व के नाम $attr->getNodeName से आसान हो गया है, लेकिन पहली बार में सब <attr_1> के बच्चे तत्वों प्राप्त करने के लिए पाठ <attr_1> टैग एक है में संलग्न तक पहुँचने के लिए:

my @child_ref = $attr->getChildNodes; 

<attr_1> के लिए और <attr_2> तत्वों ->getChildNodes युक्त सूची लौटाता है बिल्कुल एक संदर्भ (XML::DOM::Text कक्षा का ऑब्जेक्ट करने के लिए), जबकि <attr_3> के लिए यह एक खाली सूची देता है। <attr_1> और <attr_2> के लिए मुझे $child_ref[0]->getNodeValue पर मूल्य प्राप्त करना चाहिए, जबकि <attr_3> के लिए मुझे undef को परिणामी हैश में रखना चाहिए क्योंकि वहां कोई टेक्स्ट तत्व नहीं है।

तो आप देखते हैं कि f समारोह के (वास्तविक जीवन में विधि ->getChildNodes) कार्यान्वयन :-) जिसके परिणामस्वरूप कोड है कि मैंने लिखा है है (सबरूटीन तत्वों <attr_1>, <attr_2> के लिए XML::DOM::Element संदर्भ की सूची के साथ प्रदान की जाती है नियंत्रित नहीं किया जा सकता है, और <attr_3>):

sub attrs_hash(@) 
{ 
    my @keys = map {$_->getNodeName} @_; # got ('attr_1', 'attr_2', 'attr_3') 
    my @child_refs = map {[$_->getChildNodes]} @_; # got 3 refs to list of XML::DOM::Text objects 
    my @values = map {@$_ ? $_->[0]->getNodeValue : undef} @child_refs; # got ('value_1', 'value_2', undef) 

    my %hash; 
    @hash{@keys} = @values; 

    %hash; 
} 
+0

मेरी इच्छा है कि आपने इसका उल्लेख आगे बढ़ाया हो। आपके द्वारा पूछे जाने वाले प्रश्न के रूप में आपको केवल उतना ही अच्छा जवाब मिलेगा। बहुत बुरा है कि यह जानकारी पहले उपलब्ध नहीं कराई गई थी। – Zaid

+0

क्यों? मुझे लगता है कि मेरे पास सही उत्तर हैं जो मुझे सूचियों और स्लाइस से संबंधित कई बिंदुओं को स्पष्ट करने की अनुमति देता है :-) – indexless

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