2009-08-10 10 views
8

क्या पर्ल लगातार आदेशित हैश कुंजी वापस करने की गारंटी है?

foreach (keys %myHash) { 
    ... do stuff ... 
} 

foreach (keys %myHash) { 
    ... do more stuff ... 
} 

की तरह कुछ को देखते हुए पर्ल एक सुसंगत क्रम में चाबियाँ पर पुनरावृति करने के लिए करता है, तो हैश परिवर्तित नहीं होता गारंटी है?

+0

जिज्ञासा से बाहर - आपको इस संपत्ति की क्या आवश्यकता है? – hillu

+1

सब कुछ और कुछ भी वोट दे रहा है? – erjiang

उत्तर

26

Yesperldoc -f keys से:

कुंजी को स्पष्ट रूप से यादृच्छिक क्रम में वापस कर दिया जाता है। वास्तविक यादृच्छिक क्रम perl के भविष्य के संस्करणों में परिवर्तन के अधीन है, लेकिन यह values या each फ़ंक्शन उत्पादन (जैसा कि हैश संशोधित नहीं किया गया है) के समान आदेश होने की गारंटी है। चूंकि पर्ल 5.8.1 सुरक्षा कारणों से पर्ल के विभिन्न रनों के बीच ऑर्डरिंग अलग है (perldoc perlsec में "एल्गोरिदमिक कॉम्प्लेक्सिटी अटैक" देखें)।

(जोर मेरा)

+12

+1 यह बहुत अच्छा होगा अगर लोगों ने कम से कम उत्कृष्ट दस्तावेज पढ़ने की कोशिश की जो पर्ल के साथ आता है। –

-2

यह एक सुंदर dicey उम्मीद है। यह शायद होगा, लेकिन चिंता क्यों? अग्रिम में कुंजी प्राप्त करें, परिणाम सहेजें, फिर सहेजे गए परिणाम पर फिर से शुरू करें। फिर, आपको उसी क्रम में कुंजी तक पहुंचने की गारंटी है। अनिर्दिष्ट कार्यान्वयन विवरण के किनारों के आसपास काम करना खतरनाक है।

संपादित करें: दस्तावेज़ में "गारंटी" मिस गया, लेकिन मुझे अभी भी लगता है कि यह उम्मीद करना खतरनाक है कि यह कभी नहीं बदलेगा। विशेष रूप से जब एक ही सिरों को प्राप्त करने के लिए सैनीर तरीके हैं।

+2

क्यों "गारंटी" के आसपास डरावना उद्धरण?यह (ए) बहुत स्पष्ट रूप से कहा गया है; (बी) बदलने की संभावना नहीं है, क्योंकि 'कुंजी' और 'मानों' के लिए यह एक ही क्रम में लौटने के लिए महत्वपूर्ण है, ताकि जब आप 'प्रत्येक' का उपयोग नहीं कर सकते हैं, तो दोनों से संबंधित हो सकता है। – derobert

0

संपादित करें:

हालांकि एक सामान्य हैश एक सुसंगत आदेश है, एक tied hash के मामले में चाबियों का आदेश अच्छी तरह से, परिभाषित नहीं के रूप में यह उपयोगकर्ता के नियंत्रित है!


हालांकि हैश कुंजी ऑर्डर नहीं बदलेगा, आपको शायद पुनर्विचार करना चाहिए कि आपको ऐसा करने की आवश्यकता क्यों है।

शायद आप हैश को दो के बजाय एक पास में संसाधित कर सकते हैं?

आपको हैश कुंजी को एक रक्षात्मक प्रोग्रामिंग अभ्यास के रूप में एक सरणी में सहेजना चाहिए, जब तक कि डेटा का आकार इतना बड़ा न हो कि डुप्लिकेट करना एक समस्या होगी। बोनस के रूप में, आप आसानी से सूची को सॉर्ट कर सकते हैं और हैश में एक अच्छी तरह परिभाषित क्रम में संसाधित कर सकते हैं। जैसे,

my @keys = sort keys %myHash; 

इस हैश को संशोधित करने, के बाद से अपने सरणी आदेश जब तक आप इसे करना चाहते हैं कभी नहीं बदलेगा के साथ कोई समस्या से बचा जाता है।

यदि आप ऐसा नहीं करते हैं, तो आपको हैश को बदलने वाले कुछ भी नहीं करने के लिए बहुत सावधान रहना होगा, अन्यथा तत्वों का क्रम बदल जाएगा। यह सुनिश्चित करने के लिए कि हैश कभी संशोधित नहीं किया गया है, Readonly मॉड्यूल में देखें।

+0

मुझे यह नहीं मिला - आपको ऐसी सुविधा के बारे में रक्षात्मक क्यों होना चाहिए जिसका परीक्षण, दस्तावेज और इस प्रकार काम करने की गारंटी है? यह एक टेक्स्ट एडिटर का उपयोग करने के रूप में मूर्खतापूर्ण लगता है और उम्मीद है कि अगर पहली बार चुपचाप विफल रहता है तो फ़ाइल को सुरक्षित रूप से दो बार सुरक्षित करें, दूसरा दूसरा सफल होगा। – moritz

+2

@ मॉरिट्स: मुद्दा यह नहीं है कि पर्ल कुंजी ऑर्डर बदलता है (या नहीं), यह है कि हैश संशोधित होने पर ऑर्डर बदल सकता है। यह उत्तर ओपी के कोडबेस के भविष्य के रखरखाव के लिए एक रक्षात्मक प्रोग्रामिंग रणनीति (अलग सरणी प्लस रीडोनली) का सुझाव दे रहा है, और पर्ल आंतरिक के साथ इसका कोई लेना-देना नहीं है। –

+3

जब तक कि मजबूत प्रदर्शन कारण न हों, मैं हमेशा क्रमबद्ध करने की कोशिश करता हूं। कोड द्वारा अक्सर काट दिया जाता है जो निश्चित रूप से एक निश्चित आदेश की अपेक्षा करता है और रहस्यमय तरीके से असफल होने लगते हैं जब प्रतीत होता है कि असंबद्ध परिवर्तनों के परिणामस्वरूप चाबियों का एक अलग क्रम होता है। – ysth