2012-01-18 22 views
13

मुझे असीमित अनुक्रम बनाने की आवश्यकता है जिसमें तत्वों के बाद एक अनंत अनुक्रम होता है।दोहराने वाले तत्वों के साथ अनंत अनुक्रम

let l = [1; 2; 3; 4] 
let s = seq { while true do yield! l } 

वहाँ एक मानक तरीका (समारोह) यह करने के लिए है:

[1; 2; 3; 4; 1; 2; 3; 4; 1; 2; 3; 4; ...] 

तो मैं यह लिखा?

उत्तर

17

मुझे लगता है कि इस दृष्टिकोण में आपका दृष्टिकोण अच्छा है। वहाँ पुनरावृत्ति को लागू करने के लिए कोई अंतर्निहित समारोह है, लेकिन अगर आप दृश्यों अक्सर दोहराने की आवश्यकता है, तो आप एक अपने आप को परिभाषित करने और यह Seq मॉड्यूल में उपलब्ध करा सकते हैं: के रूप में अगर

module Seq = 
    let repeat items = 
    seq { while true do yield! items } 

तो फिर तुम अच्छी तरह से Seq.repeat [ 1 .. 4 ] लिख सकते हैं, repeat एक मानक एफ # लाइब्रेरी फ़ंक्शन था, क्योंकि F # IntelliSense आपके Seq मॉड्यूल और Seq मॉड्यूल से दोनों कार्यों को दिखाता है जैसे कि उन्हें एक मॉड्यूल में परिभाषित किया गया था।

आपके कार्यान्वयन के अलावा, आप रिकर्सिव अनुक्रम अभिव्यक्ति का भी उपयोग कर सकते हैं, जो अनुक्रम उत्पन्न करते समय एक और आम पैटर्न है। while का उपयोग करने के कुछ तरीके जरूरी है (यद्यपि आप सरल पुनरावृत्ति के लिए किसी भी राज्य की जरूरत नहीं है) कार्यात्मक प्रत्यावर्तन की तुलना में: जब आप जबकि पैदा करने के लिए कुछ राज्य रखना चाहते

let rec repeat items = 
    seq { yield! items 
     yield! repeat items } 

यह दृष्टिकोण बेहतर है। उदाहरण के लिए, while का उपयोग करके सभी संख्या 1 .. उत्पन्न करना इतना अच्छा नहीं होगा, क्योंकि आपको उत्परिवर्तनीय स्थिति की आवश्यकता होगी। प्रत्यावर्तन का उपयोग करके आप एक ही बात लिख सकते हैं:

let rec numbersFrom n = 
    seq { yield n 
     yield! numbersFrom (n + 1) } 
3

मुझे नहीं लगता कि इसके लिए एक मुहावरे है, और आपके पास क्या ठीक है, लेकिन यहां कुछ विकल्प हैं।

आप एक सरणी के लिए अपने परिणाम को बदलते हैं तो आप

let a = [|1; 2; 3; 4|] 
let s = Seq.initInfinite (fun i -> a.[i % a.Length]) 

का उपयोग करना तुम्हारे पास क्या है क्या कर सकते हैं, आप भी

let l = [1; 2; 3; 4] 
let s = Seq.initInfinite (fun _ -> l) |> Seq.concat 

कर सकता है, लेकिन यह कोई छोटा है।

+4

एक पकड़ लिया यहाँ: 'Seq.initInfinite' केवल अनन्तता के कुछ मूल्यों के लिए अनंत अनुक्रम उत्पन्न करता है। [प्रलेखन] से (http://msdn.microsoft.com/en-us/library/ee370429.aspx): "इटरेशन Int32.MaxValue तक जारी रह सकता है।" –

+1

यह कोर लिब की अनंत की परिभाषा को फिट करता है, जो एक उपयोगी कामकाजी परिभाषा है। – Daniel

1

यह किसी भी सहायक वस्तुएं बनाने के बिना इसे (अधिक या कम) एक-लाइनर के रूप में करेगा।

let s = seq { while true do 
       for i in 1 .. 4 -> i } 
+0

[1; 2; 3; 4] सूची केवल एक उदाहरण था। हकीकत में मेरे पास वस्तुओं की एक सूची है जिसे मुझे अनुक्रम बनाने की आवश्यकता है। – Max

1

डैनियल जवाब देने के लिए इसी तरह की है, लेकिन यह एक समारोह में encapsulating, और कहा कि समारोह का नाटक Seq मॉड्यूल में है:

module Seq = 
    let infiniteOf repeatedList = 
     Seq.initInfinite (fun _ -> repeatedList) 
     |> Seq.concat 

// Tests 
let intList = [1; 2; 3; 4] 
let charList = ['a'; 'b'; 'c'; 'd'] 
let objList = [(new System.Object()); (new System.Object()); (new System.Object()); (new System.Object())] 
do 
    Seq.infiniteOf intList |> Seq.take 20 |> Seq.iter (fun item -> printfn "%A" item) 
    Seq.infiniteOf charList |> Seq.take 20 |> Seq.iter (fun item -> printfn "%A" item) 
    Seq.infiniteOf objList |> Seq.take 20 |> Seq.iter (fun item -> printfn "%A" item) 
संबंधित मुद्दे