2012-03-04 21 views
5

मैं इसतुलना और मान्य डेटा संरचनाओं

[ 
{ foo => { "<=" => 75 } }, 
{ bar => { "==" => 20 } }, 
{ baz => { ">=" => 5 } }, 
] 

तरह की स्थिति को व्यक्त करने hashrefs के arrayref के खिलाफ यह एक

{ foo => 65, bar => 20, baz => 15 } 

तरह hashrefs की जाँच करें और एक सच्चे मान अगर सभी शर्तों को पूरा कर रहे हैं करने के लिए है।

दो डेटा संरचनाओं में से कोई भी पूर्व निर्धारित नहीं है। एक डेटाबेस में स्ट्रिंग को पार्स करने से बनाया गया है, दूसरा उपयोगकर्ता इनपुट पार्सिंग से बनाया गया है।

उपरोक्त मामले में, मैं सच वापसी होगी, लेकिन अगर मैं

[ 
{ foo => { "<=" => 60 } }, 
{ bar => { "==" => 20 } }, 
{ baz => { ">=" => 5 } }, 
] 

मैं, झूठी वापसी होगी क्योंकि पहली hashref में foo नहीं है < = 60.

के खिलाफ hashref जाँच सवाल यह है कि ऐसा करने के लिए सबसे अच्छी रणनीति क्या है?

मैं eval

  • 5 अलग अलग पहले से बने subrefs (के लिए>, <, < =,> = मामले प्रति एक के बीच में उचित एक के खिलाफ जाँच के माध्यम से subrefs की एक श्रृंखला का निर्माण

    • की सोच रहा हूँ और ==)

    क्या मैं गलत पथ को पूरी तरह से नीचे जा रहा हूं? और यदि नहीं, तो सबसे अच्छा, eval या पूर्व-निर्मित कार्य क्या है?

    मैंने पैराम्स में देखा है :: मान्य है लेकिन मुझे चिंता है कि यह बहुत अधिक ओवरहेड होगा, और मुझे वैसे भी कॉलबैक बनाना होगा।

  • +0

    एकल हैश रेफ की एक सरणी केवल उपयोगी होगी यदि आपके पास डुप्लिकेट कुंजी थी। जैसे '[{foo => ...}, {foo => ...}] 'मुझे संदेह है कि आपके पास डुप्लिकेट कुंजी नहीं है, जो यह अनावश्यक बनाता है, और आपको शायद एक हैश का उपयोग करना चाहिए, और सरणी को छोड़ना चाहिए। – TLP

    उत्तर

    7

    इसके बजाए कोड संदर्भों का उपयोग करें, और आप सत्यापनकर्ताओं के पास जाने के लिए तैयार होंगे। मैंने आपकी हालत-संरचना को सरल बना दिया। वहां तक ​​अतिरिक्त सरणी स्तर होने की आवश्यकता नहीं है, जब तक कि आपके पास डुप्लिकेट हैश कुंजी न हो, जो मुझे लगता है कि आप नहीं करते हैं।

    सरल sub { $_[0] <= 75 } बस तर्कों के पहले मान की तुलना करेगा। डिफ़ॉल्ट रूप से, subroutine में मूल्यांकन किया गया अंतिम मान इसके वापसी मूल्य होगा।

    use v5.10; 
    use strict; 
    use warnings; 
    
    my $in = { foo => 65, bar => 21, baz => 15 }; 
    
    my $ref = { 
        foo => sub { $_[0] <= 75 } , 
        bar => sub { $_[0] == 20 } , 
        baz => sub { $_[0] >= 5 } , 
    }; 
    
    for my $key (keys %$in) { 
        if ($ref->{$key}($in->{$key})) { 
         say "$key : Valid"; 
        } else { 
         say "$key : Invalid"; 
        } 
    } 
    

    आउटपुट:

    bar : Invalid 
    baz : Valid 
    foo : Valid 
    
    +0

    उत्तर के लिए धन्यवाद। – simone

    +0

    @ सिमोन आपका स्वागत है। – TLP

    1

    TLP के जवाब पर निर्माण करने के लिए, आप भी आसानी से गुमनाम बाद के चरणों के लिए अपने मौजूदा सरणी के-हैश से बना सकते हैं:

    my $array_of_hashes = [ 
        { foo => { "<=" => 75 } }, 
        { bar => { "==" => 20 } }, 
        { baz => { ">=" => 5 } }, 
    ]; 
    
    my $ref = {}; 
    foreach my $entry (@$array_of_hashes) { 
        my ($key, $subhash) = %$entry; 
        my ($op, $num) = %$subhash; 
        $ref->{$key} = { 
         '<=' => sub { $_[0] <= $num }, 
         '==' => sub { $_[0] == $num }, 
         '>=' => sub { $_[0] >= $num }, 
        }->{$op}; 
    } 
    

    इसका मतलब यह है कि आपके पास अपने मूल सरणी के हैंश में प्रत्येक फ़ील्ड के लिए केवल एक चेक है। आप कई हो सकता है, तो चीजें थोड़ा अधिक मुश्किल हो, लेकिन आप हमेशा कुछ इस तरह कर सकता है:

    my $ref = {}; 
    foreach my $entry (@$array_of_hashes) { 
        my ($key, $subhash) = %$entry; 
        my ($op, $num) = %$subhash; 
        my $chain = $ref->{$key} || sub {1}; 
        $ref->{$key} = { 
         '<=' => sub { $_[0] <= $num and $chain->($_[0]) }, 
         '==' => sub { $_[0] == $num and $chain->($_[0]) }, 
         '>=' => sub { $_[0] >= $num and $chain->($_[0]) }, 
        }->{$op} || $chain; 
    } 
    

    Ps। अगर कोई यह सोच रहा है कि यह कोड संभवतः कैसे काम कर सकता है, तो जवाब है: closures।विशेष रूप से, जब लूप के अंदर उन अज्ञात सबस बनाए जाते हैं, तो वे लूप के वर्तमान पुनरावृत्ति के अंत में इन चर के दायरे से बाहर होने के बाद भी, लेक्सिकल चर $num और $chain पर संदर्भ बनाए रखते हैं। तो, उसके बाद हमेशा के लिए, उन चरों को सुरक्षित रूप से गिलहरी कर दिया जाएगा, केवल हमारे द्वारा बनाए गए सबराउटिन से पहुंचा जा सकता है।

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