2012-09-29 18 views
5

एक साधारण उदाहरण के रूप में, मान लीजिए कि मेरे पास L संख्याओं की एक सूची है और मैं कुछ विशिष्ट संख्या से अधिक पहला तत्व ढूंढना चाहता हूं X। मैं इस तरह सूची comprehensions के साथ ऐसा कर सकता है:एरलांग: कुछ स्थितियों से मेल खाने वाली सूची में पहला तत्व (शेष तत्वों का मूल्यांकन किए बिना)

([email protected])24> L = [1, 2, 3, 4, 5, 6].    
[1,2,3,4,5,6] 
([email protected])25> X = 2.5. 
2.5 
([email protected])26> [First | _] = [E || E <- L, E > X]. 
[3,4,5,6] 
([email protected])27> First. 
3 

लेकिन इस संभावित बहुत अक्षम लगता है, के बाद से सूची बहुत लंबी हो सकती है और पहले मैच जल्दी पर हो सकता है। तो मैं सोच रहा हूं कि या तो ए) क्या ऐसा करने का कोई प्रभावी तरीका है जो पहले मैच के बाद सूची में शेष तत्वों का मूल्यांकन नहीं करेगा? या बी) जब यह संकलित हो जाता है, तो क्या एरलांग बाकी तुलनाओं को किसी भी तरह से अनुकूलित करता है?

यह मैं कैसे प्राप्त होगा मैं सी में के लिए क्या देख रहा हूँ है:

int first_match(int* list, int length_of_list, float x){ 
    unsigned int i; 
    for(i = 0; i < length_of_list, i++){ 
     if(x > list[i]){ return list[i]; } /* immediate return */ 
    } 
    return 0.0; /* default value */ 
} 

उत्तर

11

अच्छी तरह से, जैसे

firstmatch(YourList, Number) -> 
    case lists:dropwhile(fun(X) -> X =< Number end, YourList) of 
    [] -> no_solution; 
    [X | _] -> X 
    end. 
+1

अच्छा। यह मेरे समाधान से अधिक संक्षिप्त है। मुझे यह सत्यापित करने के लिए थोड़ा सा प्रयास करना पड़ा कि 'असफल' वास्तव में पहले असफल मैच के बाद मूल्यांकन करना बंद कर देता है। मैंने इसे एक फ़ंक्शन में लपेट लिया जो आपको एक फ़ंक्शन के रूप में स्थिति निर्दिष्ट करने देता है (तर्क को उलटा किए बिना): https://gist.github.com/3807110 – dantswain

3

यहाँ मैं साथ आने के लिए सक्षम था। मैं अभी भी जानना चाहता हूं कि क्या कोई बेहतर जवाब है और/या यदि सबसे सरल चीज अनुकूलित हो जाती है (जितना अधिक मैं इसके बारे में सोचता हूं, उतना ही मुझे शक है)।

-module(lazy_first). 

-export([first/3]). 

first(L, Condition, Default) -> 
    first(L, [], Condition, Default). 

first([E | Rest], Acc, Condition, Default) -> 
    case Condition(E) of 
    true -> E; 
    false -> first(Rest, [E | Acc], Condition, Default) 
    end; 

first([], _Acc, _Cond, Default) -> Default. 

उदाहरण:

14> lazy_first:first([1, 2, 3, 4, 5], fun(E) -> E > 2.5 end, 0.0). 
3 
15> lazy_first:first([1, 2, 3, 4, 5], fun(E) -> E > 5.5 end, 0.0). 
0.0 

संपादित

यहाँ एक संचायक के बिना एक संस्करण है।

first([E | Rest], Condition, Default) -> 
    case Condition(E) of 
    true -> E; 
    false -> first(Rest, Condition, Default) 
    end; 

first([], _Cond, Default) -> Default. 
+2

है कि क्या वहाँ एक अंतर्निहित शॉर्टकट के प्रश्न को हल नहीं कर सकता है, लेकिन यह निश्चित रूप से की तरह दिखता है अपना खुद का रोल करने का उचित तरीका ... आपके जमाकर्ता को छोड़कर अनावश्यक लगता है। – macintux

+0

वास्तव में अच्छा बिंदु :) जो वास्तव में इसे थोड़ा सा सरल बनाता है। – dantswain

3

कुछ यहां एक त्वरित समाधान है:

first_greater([],_) -> undefined; 
first_greater([H|_], Num) when H > Num -> H; 
first_greater([_|T], Num) -> first_greater(T,Num).