2009-02-12 13 views
8

मैं सोच रहा हूं कि कोई मूर्खतापूर्ण एक-लाइनर या मानक-वितरण पैकेज/फ़ंक्शन है जिसका उपयोग मैं दो बिर्ल हैंश की तुलना करने के लिए केवल अंतर्निहित, गैर-धन्य प्रकारों के साथ कर सकता हूं। हैंश समान नहीं हैं (उनके पास समान स्मृति पते नहीं हैं)।मैं एक साधारण पर्ल हैश समकक्ष तुलना कैसे करूं?

मैं उथले हैश और नेस्टेड संग्रह के साथ हैश के लिए दोनों के लिए इस सवाल का जवाब जानना चाहते हैं, लेकिन मैं समझता हूँ कि उथले हैश एक बहुत सरल समाधान हो सकता है।

टीआईए!

उत्तर

13

कुछ cmp_deeply तरह Test::Deep में उपलब्ध है?

+1

निश्चित रूप से, मुझे लगता है कि टेस्ट :: डीप :: eq_deeply वही है जो मैं ढूंढ रहा हूं! – cdleary

1

मुझे नहीं पता कि कोई आसान तरीका है या एक अंतर्निहित पैकेज है, और मुझे नहीं पता कि क्या होता है जब आप %hash1 == %hash2 (लेकिन शायद यह नहीं है), लेकिन यह आपके रोल को रोल करना मुश्किल नहीं है खुद:

sub hash_comp (\%\%) { 
    my %hash1 = %{ shift }; 
    my %hash2 = %{ shift }; 
    foreach (keys %hash1) { 
    return 1 unless defined $hash2{$_} and $hash1{$_} == $hash2{$_}; 
    delete $hash1{$_}; 
    delete $hash2{$_}; 
    } 
    return 1 if keys $hash2; 
    return 0; 
} 

untested है, लेकिन अगर हैश सभी एक ही तत्व और सभी एक ही मान लौटाना चाहिए 0। इस समारोह को बहुआयामी हैश के लिए खाते में संशोधित करना होगा।

यदि आप मानक वितरण से कुछ चाहते हैं, तो आप use Data::Dumper; कर सकते हैं और केवल दो हैश को दो स्केलर वैरिएबल में डंप कर सकते हैं, फिर समानता के तारों की तुलना करें। यह काम कर सकता है।

वहाँ भी एक पैकेज पर CPAN FreezeThaw कि ऐसा लगता है कि आप क्या चाहते हैं करता है कहा जाता है।

ध्यान दें कि स्मार्ट मैच का उपयोग करने के लिए (यहां दोहराया नहीं गया है क्योंकि यह पहले से पोस्ट किया गया है), आपको use feature; और यह केवल पर्ल 5.10 के लिए उपलब्ध होगा। लेकिन अभी भी पर्ल 5.8.8 का उपयोग कर रहा है, है ना?

+1

"लेकिन अभी भी पर्ल 5.8.8 का उपयोग कर रहा है, है ना?" मैं हूँ। :-) – cdleary

+0

इसके अलावा "==" तुलना स्केलर संदर्भ को बल देती है, इसलिए यह तत्वों की संख्या की तुलना करती है। – cdleary

+0

@cdleary: मैंने कहा कि क्योंकि, मैक ओएस एक्स के उपयोगकर्ता के रूप में, सभी ओएस एक्स उपयोगकर्ता डिफ़ॉल्ट रूप से 5.8.8 का उपयोग कर रहे हैं, जब तक कि वे इसे अपग्रेड करने के अपने रास्ते से बाहर नहीं जाते। –

4

उह ओह [यह किसी के द्वारा एक जवाब जो अपने उत्तर हटा दिया गया के लिए एक प्रतिक्रिया थी।]

!

%a ~~ %b && [sort values %a] ~~ [sort values %b] 

यह जांच नहीं करता है कि मान एक ही कुंजी के हैं या नहीं।

#! perl 
use warnings; 
use strict; 

my %a = (eat => "banana", say => "whu whu"); # monkey 
my %b = (eat => "whu whu", say => "banana"); # gorilla 
print "Magilla Gorilla is always right\n" 
    if %a ~~ %b && [sort values %a] ~~ [sort values %b]; 
+0

'वास्तव में महाकाव्य अनुपात का एक साहसी पर्ल प्रोग्रामर है जो स्मार्ट-पैंट '~~ ऑपरेटर का उपयोग करने की हिम्मत करता है। :) – tchrist

0

उथले हैश के लिए:

(grep {exists %hash2{$_}} keys %hash1) > 0 
0

हैश सरणियों, जहां हर मूल्य उसके प्रमुख इस प्रकार में casted किया जा सकता है (लेकिन आप चाबियों का आदेश पता नहीं होगा)। तो:

(join("",sort(%hash1)) eq join("",sort(%hash2))) 

ओह, रुको, कि क्योंकि वहाँ कुछ बढ़त मामलों रहे हैं काम नहीं करेगा, जैसे:

%hash1 = { 'aaa' => 'aa' }; 
%hash2 = { 'aa' => 'aaa' }; 

तो यह में शामिल होने के (में एक चरित्र का उपयोग करने के लिए सबसे अच्छा है) है कि आप पता चल जाएगा किसी भी कुंजी या मूल्य में कभी प्रकट नहीं होता है। यदि मूल्य बीएलओबी हैं, तो यह एक बड़ी समस्या होगी, लेकिन किसी और चीज के लिए आप नल चार "\ 0" का उपयोग कर सकते हैं।

(join("\0",sort(%hash1)) eq join("\0",sort(%hash2))) 

थोड़े बदसूरत लग रहा है, मुझे पता है, लेकिन अगर दो हैश एक उथले रास्ता है, जो है ज्यादातर लोगों के लिए क्या देख रहे में बराबर हैं यह जाँच के लिए क्या करेंगे।

-1

हैश को एक्सएमएल फाइलों में कनवर्ट करें और तुलना करें, और हाँ आप बहुस्तरीय उपयोग कर सकते हैं।

sub isEqualHash 
{ 
    my ($self,$hash1, $hash2) = @_; 
    my $file1 = "c:/neo-file1.txt"; 
    my $file2 = "c:/neo-file2.txt"; 
    my $xmlObj = XML::Simple->new(); 
    my $dummy_file = $xmlObj->XMLout($hash1,OutputFile => $file1); 
    my $dummy_file = $xmlObj->XMLout($hash2,OutputFile => $file2); 

    open FILE, "<".$file1; 
    my $file_contents1 = do { local $/; <FILE> }; 
    close(FILE); 

    open FILE, "<".$file2; 
    my $file_contents2 = do { local $/; <FILE> }; 
    close(FILE); 

    if($file_contents1 eq $file_contents2) 
    { 
     return "Passed"; 
    } 
    else 
    { 
     return "Failed"; 
    } 
} 
1

आपके प्रश्न के लिए धन्यवाद।

मैं टेस्ट :: अधिक :: परिणाम के रूप में eq_hash इस्तेमाल किया।

0

आप Test::Deep::NoTest में eq_deeply उपयोग कर सकते हैं। यह सिर्फ एक बूलियन है कि आप देख सकते हैं, main module का परीक्षण क्षमताओं के अतिरिक्त भूमि के ऊपर के बिना देता है।

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