2010-03-28 4 views
10

मुझे एक डेटा संरचना मिली है जो हैश है जिसमें हैश की एक सरणी है। मैं वहां पहुंचना चाहता हूं और पहले हैश को खींचना चाहता हूं जो एक मूल्य से मेल खाता है जिसे मैं ढूंढ रहा हूं। मैं इस की कोशिश की:पर्ल की शिफ्ट शिकायत क्यों करती है 'शिफ्ट करने के लिए तर्क 1 का प्रकार सरणी होना चाहिए (grep iterator नहीं)।'

my $result = shift grep {$_->{name} eq 'foo'} @{$hash_ref->{list}}; 

लेकिन वह मुझे इस त्रुटि देता है: Type of arg 1 to shift must be array (not grep iterator). मैं गया है grep के लिए perldoc फिर से पढ़ सकते हैं और मुझे लगता है कि मैं क्या कर रहा हूँ समझ में आता है। grep एक सूची देता है, है ना? क्या यह गलत संदर्भ में है?

मैं अब के लिए एक अस्थायी चर का उपयोग करूंगा, लेकिन मैं यह जानना चाहता हूं कि यह क्यों काम नहीं करता है।

उत्तर

18

A list isn't an array

my ($result) = grep {$_->{name} eq 'foo'} @{$hash_ref->{list}}; 

... हालांकि नौकरी करना चाहिए। सूची संदर्भ में grep से वापसी ले लो, लेकिन पहले के अलावा किसी भी मूल्य को असाइन न करें।

+5

मुझे लगता है कि मैं अपने व्हाइटबोर्ड पर 'एक सूची एक सरणी नहीं है' लिखूंगा। धन्यवाद। – wes

+0

अब उन एफएक्यू के लिए एक बेहतर जवाब है: http://www.effectiveperlprogramming.com/blog/39 –

+0

@brian d foy - अक्सर पूछे जाने वाले प्रश्न कब अपडेट होते हैं? (यानी हम इसे पर्ल 5 संस्करण 10 की एक बिंदु रिलीज में देखेंगे, या यह संस्करण 12 में होगा?) – Quentin

17

मुझे लगता है कि लिखने के लिए एक बेहतर तरीका यह इस होगा:

use List::Util qw/first/; 

my $result = first { $_->{name} eq 'foo' } @{ $hash_ref->{list} }; 

इतना ही नहीं यह और अधिक स्पष्ट तुम क्या करने के लिए तेजी से, यह भी हो सकता है, क्योंकि यह आपके सरणी grepping बंद हो जाएगा कोशिश कर रहे हैं क्या होगा एक बार यह मिलान तत्व मिला है।

2

एक और तरीका है यह करने के लिए:

my $result = (grep {$_->{name} eq 'foo'} @{$hash_ref->{list}})[0]; 

ध्यान दें कि grep को पहले तर्क के आसपास curlies इस मामले में अनावश्यक हैं, तो आप के साथ ब्लॉक सेटअप और टियरडाउन लागत से बच सकते

my $result = (grep $_->{name} eq 'foo', @{$hash_ref->{list}})[0]; 

“List value constructors” in perldata सूचियों की सदस्यता सबस्क्राइबिंग:

A list value may also be subscripted like a normal array. You must put the list in parentheses to avoid ambiguity. For example:

# Stat returns list value. 
$time = (stat($file))[8]; 

# SYNTAX ERROR HERE. 
$time = stat($file)[8]; # OOPS, FORGOT PARENTHESES 

# Find a hex digit. 
$hexdigit = ('a','b','c','d','e','f')[$digit-10]; 

# A "reverse comma operator". 
return (pop(@foo),pop(@foo))[0]; 

जैसा कि मुझे याद है, हमें यह सुविधा मिली है जब Randal Schwartz ने मजाक कर सुझाव दिया, और Chip Salzenberg- उन दिनों में पैचिंग मशीन कौन थी - इसे शाम को लागू किया गया।

अद्यतन: खोज की एक बिट से पता चलता है कि मेरे मन में यह सुविधा $coderef->(@args) थी। प्रतिबद्ध संदेश भी वार्तालाप लॉग करता है!

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