2010-01-18 8 views
6

हाल ही में मैं कार्यात्मक प्रोग्रामिंग के बारे में बहुत कुछ सोच रहा हूं। पर्ल इस तरह से जाने के लिए कुछ औजार प्रदान करता है, हालांकि ऐसा कुछ है जिसे मैं अभी तक नहीं ढूंढ पाया।मैं कम से कम कोड के साथ पर्ल में प्रोटोटाइप के Enumerator.detect के बराबर कैसे करूं?

प्रोटोटाइप समारोह प्रगणक के लिए पता लगाने है, विवरण बस यह है:

Enumerator.detect(iterator[, context]) -> firstElement | undefined 
Finds the first element for which the iterator returns true. 

इस मामले में गणनाकार किसी भी सूची जबकि इटरेटर एक समारोह, जिनमें से प्रत्येक तत्व पर बारी में लागू किया जाता है के लिए एक संदर्भ है सूचि।

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

मैं ऐसे समाधान की भी तलाश कर रहा हूं जिसमें कोई अतिरिक्त मॉड्यूल लोड नहीं करना पड़ेगा, इसलिए यदि संभव हो तो इसे केवल बिल्टिन के साथ किया जाना चाहिए। और अगर संभव हो, यह उदाहरण के लिए इस रूप में के रूप में संक्षिप्त होना चाहिए:

my @result = map function @array; 
+7

फॉर्म के सवाल को देखना अच्छा लगता है "लैंगेज एक्स से ए के बराबर लैंगेज एक्स क्या है?" ए क्या करता है इसकी व्याख्या के साथ। धन्यवाद। – daotoad

उत्तर

15

आप कहते हैं कि आप एक मॉड्यूल नहीं करना चाहते हैं, लेकिन यह वास्तव में List::Util में first समारोह क्या करता है। यह एक कोर मॉड्यूल है, इसलिए यह हर जगह उपलब्ध होना चाहिए।

use List::Util qw(first); 
my $first = first { some condition } @array; 

यदि आप मॉड्यूल का उपयोग न करने का आग्रह करते हैं, तो आप सूची :: उपयोग के कार्यान्वयन की प्रतिलिपि बना सकते हैं। अगर किसी को ऐसा करने का एक तेज़ तरीका पता था, तो वह वहां होगा। (ध्यान दें कि सूची :: उपयोग में एक एक्सएस कार्यान्वयन शामिल है, इसलिए यह किसी भी शुद्ध-पर्ल दृष्टिकोण से अधिक तेज़ है। इसमें first का शुद्ध-पर्ल संस्करण भी है, सूची :: उपयोग :: पीपी।)

ध्यान दें कि परीक्षण किया जा रहा मान $_ और पैरामीटर के रूप में subroutine को पास किया गया है। यह एक सुविधा है जब आप first { some condition} @values फॉर्म का उपयोग कर रहे हैं, लेकिन अगर आप नियमित सबराउटिन का उपयोग कर रहे हैं तो आपको याद रखना होगा। कुछ और उदाहरण:

use 5.010; # I want to use 'say'; nothing else here is 5.10 specific 
use List::Util qw(first); 

say first { $_ > 3 } 1 .. 10; # prints 4 

sub wanted { $_ > 4 }; # note we're using $_ not $_[0] 
say first \&wanted, 1 .. 10; # prints 5 

my $want = \&wanted;   # Get a subroutine reference 
say first \&$want, 1 .. 10; # This is how you pass a reference in a scalar 

# someFunc expects a parameter instead of looking at $_ 
say first { someFunc($_) } 1 .. 10; 
+4

+1 सूची :: उपयोग और सूची :: MoreUtils बहुत कार्यात्मक हैं - आखिरकार, उनमें 'कमी' भी शामिल है। :) – Ether

+0

व्याख्या करने के लिए धन्यवाद।एक और मॉड्यूल में आने के साथ मेरा मुख्य गपशप यह था कि मेरा बॉयलरप्लेट थोड़ा अधिक हो रहा था, लेकिन इस बिंदु पर मुझे लगता है कि मैं टूलसेट को तोड़ने से नहीं बच सकता। इसके अलावा, आपके बाद के स्पष्टीकरण में, मैं वास्तव में इन दो रूपों में उनका उपयोग करूँगा: मेरा $ res = first some_func, @array; जहां somefunc $ _ पर एक उप अभिनय है; और: मेरा $ res = पहले some_func ($ _, 5), @array; जहां some_func @_ पर उप-अभिनय है। (कम से कम मुझे उम्मीद है कि वे मानचित्र के लिए वैसे ही काम करेंगे।) (अरघ, टिप्पणियों में कोई प्रारूपण नहीं :() – Mithaldu

5

untested है के बाद से मैं इस मशीन पर पर्ल की जरूरत नहीं है, लेकिन:

my $first = first { sub performing test } @list; 

ध्यान दें कि यह नहीं करता है:

sub first(\&@) { 
    my $pred = shift; 
    die "First argument to "first" must be a sub" unless ref $pred eq 'CODE'; 
    for my $val (@_) { 
     return $val if $pred->($val); 
    } 
    return undef; 
} 

तब के रूप में उपयोग सूची में कोई मिलान नहीं है और सूची में मौजूद तत्वों में से एक अनिर्धारित मान है और वह मिलान है।

+3

यह सूची :: Util :: PP में संस्करण जैसा ही है (सिवाय इसके कि एक लूप के लिए एक लेक्सिकल वैरिएबल का उपयोग नहीं करें) – cjm

+0

जानना अच्छा है। जैसा कि मैंने कहा था कि यह पूरी तरह से कफ से बाहर था। – Dan

+2

एक व्याख्यात्मक चर का उपयोग न करने का कारण यह है कि यह सब को परीक्षण किए जाने वाले मान को संदर्भित करने की अनुमति देता है '$ _ [0]' (जैसा कि आपको अपने संस्करण में करना होगा) के बजाय '$ _'। – cjm

4
बस अपने यहाँ नहीं के बाद से

, पहले की एक पर्ल समारोह परिभाषा यह है कि अपने ब्लॉक के लिए $_ localizes:

sub first (&@) { 
    my $code = shift; 
    for (@_) {return $_ if $code->()} 
    undef 
} 

my @array = 1 .. 10; 
say first {$_ > 5} @array; # prints 6 

यह ठीक से काम करते हैं, मैं, इस संस्करण का उपयोग वकालत नहीं करते क्योंकि List::Util एक कोर है मॉड्यूल (डिफ़ॉल्ट रूप से स्थापित), और first का कार्यान्वयन आमतौर पर एक्सएस संस्करण (सी में लिखा गया) का उपयोग करेगा जो बहुत तेज है।

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