2010-07-19 14 views
5

की खोज में एक सूची के माध्यम से फ़ंक्शन को कार्यान्वित करना मुझे एरलांग में कोडिंग समस्या मिली है जो शायद एक सामान्य डिज़ाइन पैटर्न है, लेकिन मुझे इसे हल करने के तरीके पर कोई जानकारी नहीं मिल रही है।डिजाइन पैटर्न? पहले {सफलता} परिणाम

मुझे एक सूची मिली है। मैं एल में प्रत्येक तत्व के लिए एक फ़ंक्शन एफ लागू करना चाहता हूं, और यह एल में सभी तत्वों में एक साथ चल रहा है। एफ (एलिमेंट) के लिए प्रत्येक कॉल या तो सफल या असफल हो जाएगी; अधिकांश मामलों में यह असफल हो जायेगी, लेकिन कभी-कभी यह एल

के भीतर एक विशिष्ट तत्व के लिए सफल होगा/जब वायुसेना (तत्व) सफल होता है, मैं "सफलता" लौटाना चाहते हैं और के लिए च के सभी आमंत्रण समाप्त एल में अन्य तत्वों - पहली "सफलता" सभी मैं में दिलचस्पी रखता हूँ है दूसरी ओर, यदि च (तत्व) एल में प्रत्येक तत्व के लिए विफल रहता है, तो मैं वापस जाने के लिए चाहते हैं "असफल"।।

एक मामूली उदाहरण के रूप में, मान लें कि एल पूर्णांक की एक सूची है, और एफ रिटर्न {सफलता} अगर एल में कोई तत्व 3 है, या किसी अन्य मान के लिए {विफल} है। यदि एल में कोई 3 एस है तो मैं जितनी जल्दी हो सके खोजना चाहता हूं; मुझे परवाह नहीं है देखते हैं कितने 3s, कम से कम एक 3 से मौजूद है या नहीं, या नहीं। च ऐसा दिखाई दे सकता:

f(Int) -> 
    case Int of 
    3 -> {success}; 
    _ -> {fail} 
    end. 

मैं Ints की एक सूची के माध्यम से कैसे पुनरावृति पता करें कि सूची कम से कम एक 3, शामिल हैं और जितनी जल्दी वापसी संभव के रूप में करने के लिए कर सकते हैं?

निश्चित रूप से यह एक आम कार्यात्मक डिजाइन पैटर्न है, और मैं सिर्फ गूगल के भीतर सही खोज शब्दों का उपयोग नहीं कर रहा हूँ ...

उत्तर

2

जैसा कि पहले से ही आपके समाधान का उत्तर दिया गया है सूचियों का उपयोग करना है: कोई/2।

देखकर कि आप इसके बारे में एक समवर्ती संस्करण चाहते हैं:

any(F, List) -> 
    Parent = self(), 
    Pid = spawn(fun() -> spawner(Parent, F, List) end), 
    receive {Pid, Result} -> Result 
    end, 
    Result. 

spawner(Parent, F, List) -> 
    Spawner = self(), 
    S = spawn_link(fun() -> wait_for_result(Spawner, Parent, length(List)) end), 
    [spawn_link(fun() -> run(S, F) end) || X <- List], 
    receive after infinity -> ok end. 

wait_for_result(Spawner, Parent, 0) -> 
    Parent ! {Spawner, false}, 
    exit(have_result); 
wait_for_result(Spawner, Parent, Children) -> 
    receive 
    true -> Parent ! {Spawner, true}, exit(have_result); 
    false -> wait_for_result(Spawner, Parent, Children -1) 
    end. 

run(S, F) -> 
    case catch(F()) of 
    true -> S ! true; 
    _ -> S ! false 
    end. 

ध्यान दें कि सभी बच्चों को ("रन" प्रक्रियाओं) जब "wait_for_children" प्रक्रिया निकास (have_result) करता है मर जाएगा।

पूरी तरह से untested ... आह, बिल्ली क्या है। मैं एक उदाहरण दूंगा:

4> play:any(fun(A) -> A == a end, [b,b,b,b,b,b,b,b]). 
false 
5> play:any(fun(A) -> A == a end, [b,b,b,b,b,b,a,b]). 
true 

अभी भी बग (और शायद वहां हैं) हो सकता है।

+0

के लिए धन्यवाद आप यह महसूस करके अनुकूलित कर सकते हैं कि 'wait_for_result/2' में हम वास्तव में रुचि नहीं रखते हैं कि कौन सा कार्यकर्ता' झूठा 'लौटाता है, बस कितने लोगों ने ऐसा किया है। तो यह हर बार सूची के पहले तत्व को हटाने के लिए पर्याप्त है। – rvirding

+0

आपको यह भी उल्लेख करना चाहिए कि 'निकास (have_result) 'सभी शेष कार्यकर्ता प्रक्रियाओं को मार डालेगा क्योंकि वे जुड़े हुए हैं (' spawn_link' से शुरू) और' have_result' सामान्य नहीं है इसलिए इसे त्रुटि निकास के रूप में माना जाता है। – rvirding

+0

आप निश्चित रूप से सही हैं। आपकी टिप्पणियों के साथ उत्तर अपडेट किया गया। –

4

ऐसा करने के मूल रूप से दो अलग अलग तरीकों से। या तो जो सूची पर दोहराता लौटने true या false चाहे वह पाता है पर निर्भर करता है अपने खुद के समारोह लिखना एक 3:

contains_3([3|_]) -> true; 
contains_3([_|T]) -> contains_3(T); 
contains_3([]) -> false. 

दूसरी सूची तत्वों पर एक परीक्षण जब तक एक एक पहले से परिभाषित फ़ंक्शन का उपयोग वास्तविक यात्रा करने के लिए है सच है और इसे परीक्षण के साथ प्रदान करते हैं। lists:any रिटर्न true या false परीक्षण कम से कम एक तत्व के लिए सफल होता है जो इस पर निर्भर:

contains_3(List) -> lists:any(fun (E) -> E =:= 3 end, List). 

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

यह करना एक बहुत ही आम बात है, लेकिन क्या यह एक डिजाइन पैटर्न के रूप में वर्गीकृत होगा जो मुझे नहीं पता। यह बहुत बुनियादी और एक अर्थ "तुच्छ" कि मैं इसे एक डिजाइन पैटर्न कॉल करने में संकोच होता है।

+0

धन्यवाद rvirding, ऐसा लगता है कि मेरा उदाहरण बहुत छोटा था ... मुझे एक जटिल और समय लेने वाला फ़ंक्शन मिला है जिसे सूची में प्रत्येक तत्व के विरुद्ध चलाने की आवश्यकता है। मैं इसे सूची में प्रत्येक तत्व के साथ एक साथ चलाने के लिए चाहता हूं, इसलिए यदि कोई है तो मैं एक सफल {सफलता} परिणाम प्राप्त कर सकता हूं। हालांकि, एक बार मुझे यह पहला {सफलता} मिल गया है, तो फ़ंक्शन को हर दूसरे सूची तत्व के विरुद्ध चलने में कोई बात नहीं है - इसमें बहुत लंबा समय लगेगा और बिना किसी लाभ के बहुत सारे संसाधन चबाएंगे। अंत में, यदि किसी भी सूची तत्वों के लिए कोई {सफलता} नहीं है, तो मुझे इसे पहचानने की भी आवश्यकता है। – monch1962

+0

मुझे उम्मीद है कि आसपास के समाधान के आधार पर एक समाधान होगा कई कार्यों को बंद करना (प्रति सूची तत्व एक), उन्हें एक साथ चलने के बाद माता-पिता प्रक्रिया में एक {सफलता} या {विफल} वापस भेज दें। एक सूची समझ और माता-पिता प्रक्रिया पर चलने वाला एक पाश प्राप्त करने का उपयोग करना आसान है; चुनौतियां (ए) प्राप्त पहली {सफलता} पर, अन्य उप-प्रक्रियाओं को एएसएपी को प्रसंस्करण और बाहर निकलने से रोकने के लिए बताती हैं, और (बी) उस मामले को संभालें जहां हर उपप्रजाति का परिणाम एक {असफल} है, इसलिए माता-पिता कभी नहीं देखता सफलता}। – monch1962

3

यह कुछ समय हो गया है क्योंकि मैंने कोई एरलांग किया है, इसलिए मैं आपको वाक्यविन्यास प्रदान करने का प्रयास नहीं कर रहा हूं, हालांकि एरलांग और ओटीपी के पास समाधान आपके लिए इंतजार कर रहा है।

स्पोन एक प्रक्रिया समारोह का प्रतिनिधित्व; इसे सूची में पुन: सक्रिय करें, जितनी प्रक्रियाएं उतनी ही कम हो रही हैं जितनी आपको लगता है कि प्रति-तत्व गणना कुशलतापूर्वक करने के लिए उपयुक्त है।

फ़ंक्शन-प्रक्रिया में प्रत्येक प्रक्रिया को लिंक करें, और पहले परिणाम को लौटने के बाद फ़ंक्शन प्रक्रिया समाप्त हो जाती है।

बाकी प्रक्रियाओं को साफ करने के लिए erlang/otp दें।

+0

यह बहुत समझ में आता है - मैं इसे आज बाद में आज़मा दूंगा। सुझाव – monch1962

0

आप plists मॉड्यूल को देखने के लिए चाहते हो सकता है: http://code.google.com/p/plists/ हालांकि मैं अगर plists:any संभालती है पता नहीं है

(क) 1 {सफलता} प्राप्त पर, अन्य उप प्रक्रियाओं प्रसंस्करण को रोकने के लिए बता & बाहर निकलें ASAP

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