2012-05-31 16 views
9

मैं एक स्ट्रिंग में फ़ंक्शन तर्कों की एक सूची को सामान्य कैसे बना सकता हूं, जैसे कि दो तर्क सूचियों को एक ही स्ट्रिंग में कनवर्ट किया जाता है अगर वे प्रभावी रूप से बराबर हैं? एल्गोरिथ्म चाहिएज्ञापन के लिए पर्ल फ़ंक्शन तर्कों को सामान्य कैसे करें?

  1. एम्बेडेड हैश और सूचियों, बल्कि संदर्भ द्वारा की तुलना में, की तुलना गहरा
  2. पर ध्यान न दें कुंजी आदेश
  3. 3 और "3"
  4. एक अपेक्षाकृत पठनीय स्ट्रिंग उत्पन्न के बीच का अंतर (आवश्यक नहीं पर ध्यान न दें हैश लेकिन डिबगिंग के लिए अच्छा करने के लिए है)
  5. अच्छी तरह से प्रदर्शन करना (XS पर्ल अधिक पसंद)

यहके लिए आवश्यक है, यानी इसके तर्कों के आधार पर फ़ंक्शन के परिणाम को कैशिंग करना।

एक strawman उदाहरण के रूप में, Memoize एक डिफ़ॉल्ट नॉर्मलाइज़र, जो विफल रहता है # 1 और # 3 के रूप में इस का उपयोग करता है: एक समय मेरे जाने के लिए नॉर्मलाइज़र लिए

$argstr = join chr(28),@_; 

था

JSON::XS->new->utf8->canonical 

हालांकि यह हाल ही में स्केलर का उपयोग कैसे किया गया था, इस आधार पर नंबर 3 और स्ट्रिंग "3" differently का इलाज करता है। यह अनिवार्य रूप से समकक्ष तर्क सूचियों के लिए अलग-अलग तार उत्पन्न कर सकता है और ज्ञापन लाभ को कम कर सकता है।

मस्ती के लिए (। कार्यों के विशाल बहुमत को पता चल जाएगा या नहीं परवाह अगर वे 3 या "3" मिलता है) मैं serializers के एक झुंड को देखा कि कौन सा अंतर को देखने के लिए 3 और "3":

Data::Dump : equal - [3] vs [3] 
Data::Dumper : not equal - [3] vs ['3'] 
FreezeThaw : equal - FrT;@1|@1|$1|3 vs FrT;@1|@1|$1|3 
JSON::PP  : not equal - [3] vs ["3"] 
JSON::XS  : not equal - [3] vs ["3"] 
Storable  : not equal - <unprintable> 
YAML   : equal - ---\n- 3\n vs ---\n- 3\n 
YAML::Syck : equal - --- \n- 3\n vs --- \n- 3\n 
YAML::XS  : not equal - ---\n- 3\n vs ---\n- '3'\n 

उन लोगों में से जो "बराबर" की रिपोर्ट करते हैं, सुनिश्चित नहीं हैं कि उन्हें हैश कुंजी ऑर्डर को अनदेखा करने के लिए कैसे प्राप्त किया जाए।

मैं पहले से ही तर्क सूची चला सकता हूं और सभी संख्याओं को स्ट्रिंग कर सकता हूं, लेकिन इसके लिए एक गहरी प्रतिलिपि बनाने की आवश्यकता होगी और # 5 का उल्लंघन होगा।

धन्यवाद!

+0

भी [टेस्ट :: अधिक] (http://metacpan.org/module/Test::More) है is_deeply, और [टेस्ट :: दीप] (http://metacpan.org/module/Test :: दीप) eq_deeply। – Ether

उत्तर

2

बहुत अधिक कोई धारावाहिक 3 और "3" अलग-अलग इलाज करेगा, क्योंकि इसमें ज्ञान नहीं है कि संख्या और स्ट्रिंग संख्या आपके लिए समान है और यह धारणा सामान्य डेटा के लिए गलत है। आपको या तो इनपुट या आउटपुट सामान्य करना होगा।

इनपुट के लिए, किसी भी स्ट्रिंग किए गए नंबर को इसके मूल्य + 0 के साथ बदलने के साथ गहरी स्कैन करेगा। यदि आप जानते हैं कि इनपुट में वास्तव में संख्याएं कहां हो सकती हैं, तो आप इस स्कैन को काफी कम कर सकते हैं।

आउटपुट के लिए, कुछ साधारण राज्य मशीन या यहां तक ​​कि regexp (हाँ, मुझे पता है कि आउटपुट नियमित नहीं है) संख्याओं के लिए संख्या-केवल स्ट्रिंग मानों को पट्टी करने के लिए पर्याप्त रूप से पर्याप्त होगा।

+0

ठीक है, नहीं, मैं उपरोक्त कई धारावाहिकों (जैसे डेटा :: डंप और फ्रीज थॉ) सूचीबद्ध करता हूं जो नहीं करते हैं। :) शायद आप का मतलब है "किसी भी अच्छे serializer * * इलाज 3 और" 3 "अलग होना चाहिए"। मुझे इतना यकीन नहीं है कि आसानी और मध्यस्थता दी गई है जिसके साथ पर्ल मूल्य स्ट्रिंग और संख्या के बीच फ़्लॉप कर सकते हैं। –

+0

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

+0

तब मैंने आउटपुट स्कैनिंग के बारे में बताया है? यह पर्याप्त तेज़ होना चाहिए। अनौपचारिक quirks के आधार पर तुलना करते समय एक महत्वपूर्ण प्लस यह है कि आप हमेशा यह सुनिश्चित कर सकते हैं कि मैन्युअल रूप से छीन लिया मूल्य वास्तव में छीन लिया जाएगा। –

2

YAML और डिफ़ॉल्ट रूप से इसकी संतान प्रकार हैश कुंजी। गहरी हैश पर सॉर्ट करने के लिए $YAML::SortKeys = 2 सेट करें।

$YAML::Stringify को एक वास्तविक मूल्य पर सेट करना और $YAML::XS::QuoteNumericStrings को गलत मान पर सेट करना आपको संख्यात्मक मानों को सामान्य करने में मदद करेगा। बाद की सेटिंग एक स्ट्रिंग मान को "अनकोट" करेगी जो एक संख्या की तरह दिखती है।


इसके अलावा, आप $Data::Dumper::Sortkeys = 1 का उपयोग Data::Dumper साथ उत्पादन क्रम को सामान्य बनाने में कर सकते हैं। $Data::Dumper::Useqq = 1 सेट करना तारों को अनवरोधित करेगा जो संख्याओं की तरह दिखते हैं।

+0

क्षमा करें, लेकिन नहीं, वाईएएमएल :: एक्सएस किसी भी धारावाहिक के रूप में व्यवहार करेगा। 'Perl -MYAML :: XS -e 'मेरी $ v =" 0333 "आज़माएं; प्रिंट YAML :: एक्सएस :: डंप $ v; $ v + 0; प्रिंट YAML :: एक्सएस :: डंप $ v; प्रिंट करें "$ v \ n"; '' –

+0

@ ओलेग वी। वोल्कोव - आपकी टिप्पणी के लिए धन्यवाद मैंने' $ YAML :: XS :: QuoteNumericStrings' के बारे में और अधिक जानकारी प्राप्त की है और मेरा जवाब संपादित किया है। लेकिन मुझे लगता है कि '0333 "' और '333" 'और' 0333' (यानी 21 9) को ओपी द्वारा अलग-अलग इनपुट के रूप में माना जाना चाहिए। – mob

+0

बस "333" बिल्कुल वही काम करेगा। –

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