تسلسلات (F#)

A تسلسل هو a logical series of عناصر الجميع of واحد نوع. تسلسلات are particularly useful when you have a قطر أيمن متوسط, ordered مجموعة of بيانات but do not necessarily expect إلى استخدم الجميع the عناصر. Individual تسلسل عناصر are محسوب فقط كـ مطلوب, so a تسلسل can provide better الأداء than a قائمة في situations في which not الجميع the عناصر are used. تسلسلات are represented بواسطة the seq<'T> نوع, which هو an اسم مستعار for IEnumerable<T>. ولذلك، أي نوع من برنامج.NET Framework يطبق System.IEnumerableيمكن استخدام كـ تسلسل. وحدة نمطية? التسلسل بتوفير الدعم ل manipulations المتضمنة تسلسلات.

تسلسل تعبيرات

على تعبير تسلسل هو تعبير يقيم إلى تتابع. يمكن أن تأخذ تعبيرات تسلسل عددا من النماذج. أبسط نموذج تحديد نطاق. ل مثال، seq { 1 .. 5 }إنشاء تسلسل الذي يحتوي على خمسة عناصر، بما في ذلك نقاط 1 و 5. يمكنك أيضا تحديد زيادة (أو حذف) بين نقطتين مزدوجتين. على سبيل المثال، ما يلي تعليمات برمجية إنشاء تسلسل أكثر 10.

// Sequence that has an increment.
seq { 0 .. 10 .. 100 }

تتكون التعبيرات تسلسل F# التعبيرات التي تنتج قيم للتسلسل. كما يمكنهم استخدام yieldالكلمة الأساسية إلى إنتاج قيم التي تصبح جزءا من تسلسل.

اتباع هو كمثال.

seq { for i in 1 .. 10 do yield i * i }

يمكنك استخدام ->عامل التشغيل بدلاً من yield، في cكـe التي يمكنك تجاهل doكلمة أساسية، كـ هو موضح في المثال التالي.

seq { for i in 1 .. 10 -> i * i }

يلي تعليمات برمجية يقوم بإنشاء قائمة أزواج إحداثي مع فهرس في صفيفة الذي يمثل الشبكة.

let (height, width) = (10, 10)
let coordinates = seq {
     for row in 0 .. width - 1 do
        for col in 0 .. height - 1 do
            yield (row, col, row*width + col) }

ifالتعبير المستخدم في تسلسل هو عامل تصفية. على سبيل المثال، إلى توليد سلسلة من الأرقام الأولية فقط، مع افتراض وجود دالة isprimeمن نوع int -> bool، توليد التسلسل كما يلي.

seq { for n in 1 .. 100 do if isprime n then yield n }

عندما تقوم باستخدام yieldأو ->المتوقع في تكرار كل تكرار إلى إنشاء عنصر مفرد في تسلسل. إذا أعطى كل تكرار تسلسل عناصر، استخدم yield!. في هذه الحالة، يتم وضع العناصر التي تم إنشاؤها في كل تكرار سلسلة إلى إنتاج التسلسل النهائي.

يمكنك يجمع تعبيرات متعددة معا في تعبير تسلسل. يتم وضع العناصر التي تم إنشاؤها بواسطة كل تعبير سلسلة معا. على سبيل مثال، راجع مقطع "امثله" الخاص بهذا الموضوع.

أمثلة

يستخدم المثال أول تعبير سلسلة يتضمن تكرار وعامل تصفية العائد إلى إنشاء صفيفة. طباعة هذه تعليمات برمجية سلسلة من الأرقام الأولية بين 1 و 100 إلى وحدة التحكم.

// Recursive isprime function.
let isprime n =
    let rec check i =
        i > n/2 || (n % i <> 0 && check (i + 1))
    check 2

let aSequence = seq { for n in 1..100 do if isprime n then yield n }
for x in aSequence do
    printfn "%d" x

تستخدم التعليمة البرمجية التالية yieldإلى إنشاء جدول الضرب الذي يتألف من المجموعات عن ثلاثة عناصر، بعضها يتكون من عمودين facإلىrs والمنتج.

let multiplicationTable =
    seq { for i in 1..9 do
            for j in 1..9 do
              yield (i, j, i*j) }

يوضح المثال التالي استخدم yield!لدمج تسلسلات الفردية في مفرد النهائية التسلسل. في this حالة, the تسلسلات for each شجرة فرعية في a ثنائي شجرة are concatenated في a عودى دالة إلى produce the final تسلسلات.

// Yield the values of a binary tree in a sequence.
type Tree<'a> =
   | Tree of 'a * Tree<'a> * Tree<'a>
   | Leaf of 'a

// inorder : Tree<'a> -> seq<'a>   
let rec inorder tree =
    seq {
      match tree with
          | Tree(x, left, right) ->
               yield! inorder left
               yield x
               yield! inorder right
          | Leaf x -> yield x
    }   
       
let mytree = Tree(6, Tree(2, Leaf(1), Leaf(3)), Leaf(9))
let seq1 = inorder mytree
printfn "%A" seq1

Using تسلسلات

تسلسلات دعم many of the same دالات كـ lists. تسلسلات also دعم العمليات such كـ تجميع و counting بواسطة using المفتاح-generating دالات. تسلسلات also دعم المزيد diverse دالات for extracting subsequences.

Many بيانات أنواع, such كـ lists, arrays, sets, و خرائط are ضمنيا تسلسلات because they are قابل للتعداد collections. A دالة that takes a تسلسل كـ an وسيطة works مع أي of the عام F# بيانات أنواع, في addition إلى أي .NET Framework نوع بيانات that implements IEnumerable<T>. تباين this إلى a دالة that takes a قائمة كـ an وسيطة, which can فقط take lists. The نوع seq<'a> هو a نوع abbreviation for IEnumerable<'a>. This means that أي نوع that implements the generic IEnumerable<T>, which يتضمن arrays, lists, sets, و خرائط في F#, و also most .NET Framework مجموعة أنواع, هو متوافق مع the seq نوع و can be used wherever a تسلسل هو expected.

وحدة نمطية? دالات

The Seq وحدة نمطية? في the Microsoft.FSharp.Collections مساحة الاسم يحتوي على دالات for working مع تسلسلات. These دالات work مع lists, arrays, خرائط, و sets كـ well, because الجميع of those أنواع are قابل للتعداد, و therefore can be treated كـ تسلسلات.

Creating تسلسلات

You can إنشاء تسلسلات بواسطة using تسلسلات expressions, كـ described previously, أو بواسطة using certain دالات.

You can إنشاء an فارغ تسلسل بواسطة using Seq.فارغ, أو you can إنشاء a تسلسل of just واحد specified عنصر بواسطة using Seq.singleton.

let seqEmpty = Seq.empty
let seqOne = Seq.singleton 10

You can استخدم Seq.init إلى إنشاء a تسلسل for which the عناصر are تاريخ الإنشاء بواسطة using a دالة that you provide. You also provide a الحجم for the تسلسل. This دالة هو just مثل قائمة.init, except that the عناصر are not تاريخ الإنشاء until you يكرر through the تسلسل. The following تعليمات برمجية illustrates the استخدم of Seq.init.

let seqFirst5MultiplesOf10 = Seq.init 5 (fun n -> n * 10)

بواسطة using Seq.ofArray و Seq.ofList <'T> دالة (F #), you can إنشاء تسلسلات من arrays و lists. However, you can also تحويل arrays و lists إلى تسلسلات بواسطة using a cast عامل. كلاهما techniques are shown في the following تعليمات برمجية.

// Convert an array to a sequence by using a cast.
let seqFromArray1 = [| 1 .. 10 |] :> seq<int>
// Convert an array to a sequence by using Seq.ofArray.
let seqFromArray2 = [| 1 .. 10 |] |> Seq.ofArray

باستخدام من Seq.cكـt، يمكنك إنشاء تسلسل من مجموعة مكتوب weakly، مثل كـ تلك المعرفة في System.Collections. أن مجموعات مثل مكتوب weakly نوع عنصر Objectو يتم تعداد باستخدام العام-غير IEnumerableالنوع. يلي تعليمات برمجية يوضح استخدم Seq.castلتحويل ArrayListفي التسلسل.

open System
let mutable arrayList1 = new System.Collections.ArrayList(10)
for i in 1 .. 10 do arrayList1.Add(10) |> ignore
let seqCast : seq<int> = Seq.cast arrayList1

يمكنك تعريف تسلسلات لانهائية بواسطة استخدام Seq.initInfinite دالة. لمثل هذا تسلسل، يجب توفير دالة تقوم بإنشاء كل عنصر من الفهرس للعنصر. تسلسلات لا نهائية محتملة نظراً لتقييم البطيئة؛ يتم تاريخ الإنشاء عناصر كـ المطلوبة بواسطة استدعاء دالة التي قمت بتحديدها. يلي تعليمات برمجية يعطي المثال تسلسل لا نهائي من عائم الأرقام يؤشر، في هذه الحالة السلسلة مع تبديل اللونين لمقلوب الأرقام بين مربعات الإعداد الصحيحة المتتابعة.

let seqInfinite = Seq.initInfinite (fun index -> 1.0 /(float index * float index) *
                                                 (if (index % 2 = 0) then 1.0 else -1.0))

Seq.بسط بإنشاء تسلسل من دالة احتساب ينتقل إلى الولاية و التحويلات لإنتاج كل العنصر التالي في التسلسل. الحالة هو قيمة فقط التي هو المستخدم لحساب كل عنصر، وتغيير العنصر كل هو محسوب. وسيطة ثانية إلى Seq.unfoldالقيمة الأولى التي يتم استخدامها ل يبدأ تسلسل. Seq.unfoldيستخدم نوع خيار للحالة، الذي يمكنك إلى ينهي التسلسل وذلك بالرجوعNoneالقيمة. يلي تعليمات برمجية يبين المثالان من تسلسلات، seq1و fib، التي تم إنشاؤها من قبل unfoldتشغيل. أول، seq1، هو تسلسل بسيط باستخدام فقط الأرقام تصل إلى 100. ثانية، fib، يستخدم unfoldإلى حساب تسلسل Fibonacci. لأن كل عنصر في تسلسل Fibonacci هو مجموع السابقة Fibonacci الرقمين، قيمة حالة هو المجموعة تلك consهوts نمطين السابقة يرقم بالتسلسل. القيمة الإفتراضية هو (1,1)، اﻷول نمطين الأرقام في تسلسل.

let seq1 = Seq.unfold (fun state -> if (state > 100) then None else Some(state, state + 1)) 0
for x in seq1 do printfn "%d" x
let fib = Seq.unfold (fun state ->
    if (snd state > 1000) then None
    else Some(fst state + snd state, (snd state, fst state + snd state))) (1,1)
for x in fib do printfn "%d" x

التعليمة البرمجية التالية هو مثال يستخدم العديد من وظائف وحدة نمطية تسلسل الموضحة هنا لإنشاء وقم بحساب قيم سلاسل متعاقبة لا نهائية. تعليمات برمجية قد يستغرق الأمر عدة دقائق إلى تشغيل.

// infiniteSequences.fs
// generateInfiniteSequence generates sequences of floating point
// numbers. The sequences generated are computed from the fDenominator
// function, which has the type (int -> float) and computes the
// denominator of each term in the sequence from the index of that
// term. The isAlternating parameter is true if the sequence has
// alternating signs.
let generateInfiniteSequence fDenominator isAlternating =
    if (isAlternating) then
        Seq.initInfinite (fun index -> 1.0 /(fDenominator index) * (if (index % 2 = 0) then -1.0 else 1.0))
    else
        Seq.initInfinite (fun index -> 1.0 /(fDenominator index))

// The harmonic series is the series of reciprocals of whole numbers.
let harmonicSeries = generateInfiniteSequence (fun index -> float index) false
// The harmonic alternating series is like the harmonic series
// except that it has alternating signs.
let harmonicAlternatingSeries = generateInfiniteSequence (fun index -> float index) true
// This is the series of reciprocals of the odd numbers.
let oddNumberSeries = generateInfiniteSequence (fun index -> float (2 * index - 1)) true
// This is the series of recipocals of the squares.
let squaresSeries = generateInfiniteSequence (fun index -> float (index * index)) false

// This function sums a sequence, up to the specified number of terms.
let sumSeq length sequence =
    Seq.unfold (fun state ->
        let subtotal = snd state + Seq.nth (fst state + 1) sequence
        if (fst state >= length) then None
        else Some(subtotal,(fst state + 1, subtotal))) (0, 0.0)

// This function sums an infinite sequence up to a given value
// for the difference (epsilon) between subsequent terms,
// up to a maximum number of terms, whichever is reached first.
let infiniteSum infiniteSeq epsilon maxIteration =
    infiniteSeq
    |> sumSeq maxIteration
    |> Seq.pairwise
    |> Seq.takeWhile (fun elem -> abs (snd elem - fst elem) > epsilon)
    |> List.ofSeq
    |> List.rev
    |> List.head
    |> snd

// Compute the sums for three sequences that converge, and compare
// the sums to the expected theoretical values.
let result1 = infiniteSum harmonicAlternatingSeries 0.00001 100000
printfn "Result: %f  ln2: %f" result1 (log 2.0)

let pi = Math.PI
let result2 = infiniteSum oddNumberSeries 0.00001 10000
printfn "Result: %f pi/4: %f" result2 (pi/4.0)

// Because this is not an alternating series, a much smaller epsilon
// value and more terms are needed to obtain an accurate result.
let result3 = infiniteSum squaresSeries 0.0000001 1000000
printfn "Result: %f pi*pi/6: %f" result3 (pi*pi/6.0)

يتم الآن البحث عن و يتم الآن البحث عن عناصر

تدعم تسلسلات الوظائف متوفر في القوائم: Seq.موجود, Seq.exists2, Seq.بحث, Seq.findIndex, Seq.pick, Seq.tryFind, و Seq.tryFindIndex. تظهر نسخ هذه الوظائف متوفر للتسلسل تقييم التسلسل فقط إلى العنصر الذي هو التي يتم البحث عنها. لرؤية أمثلة، راجع القوائم.

الحصول على Subsequences

Seq.عامل تصفية و من Seq.اختيار تشبه الدالات المطابق متوفر للقوائم، إلا أنه لا تحدث التصفية واختيار حتى التسلسل عناصر يتم تقييمها تبعاً له.

Seq.truncate إنشاء تسلسل من تسلسل آخر، ولكن قم بتحديد التسلسل إلى عدد معين من العناصر. Seq.take بإنشاء تسلسل جديد يحتوي فقط محدد رقم عناصر من بداية تسلسل. إذا كانت هناك عناصر أقل في التسلسل مما يمكنك تحديده لأخذ Seq.takeيطرح InvalidOperationException. الفرق بين Seq.takeو Seq.truncateذلك Seq.truncateلا ينتج خطأ إذا كان الرقم من عناصر هو أقل من أن الرقم الذي تحدده.

توضح التعليمة البرمجية التالية سلوك والاختلاف بين Seq.truncateو Seq.take.

let mySeq = seq { for i in 1 .. 10 -> i*i }
let truncatedSeq = Seq.truncate 5 mySeq
let takenSeq = Seq.take 5 mySeq

let truncatedSeq2 = Seq.truncate 20 mySeq
let takenSeq2 = Seq.take 20 mySeq

let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""

// Up to this point, the sequences are not evaluated.
// The following code causes the sequences to be evaluated.
truncatedSeq |> printSeq
truncatedSeq2 |> printSeq
takenSeq |> printSeq
// The following line produces a run-time error (in printSeq):
takenSeq2 |> printSeq

الإخراج، قبل حدوث الخطأ، كما يلي.

1 4 9 16 25 
1 4 9 16 25 36 49 64 81 100 
1 4 9 16 25 
1 4 9 16 25 36 49 64 81 100

باستخدام من Seq.takeWhile، يمكنك تحديد دالة دالة تقييم (دالة منطقية) وإنشاء تسلسل من تسلسل آخر من هذه العناصر من التسلسل الأصلي الذي هو دالة التقييم true، ولكن الإيقاف قبل العنصر أول الذي ترجع دالة التقييم false. Seq.تخطي إرجاع a تسلسل that skips a specified رقم of the أول عناصر of another تسلسل و إرجاع the remaining عناصر. Seq.skipWhile إرجاع a تسلسل that skips the أول عناصر of another تسلسل كـ long كـ the predicate إرجاع true, و then إرجاع the remaining عناصر, البدء مع the أول عنصر for which the predicate إرجاع false.

The following تعليمات برمجية مثال illustrates the سلوك of و differences between Seq.takeWhile, Seq.skip, و Seq.skipWhile.

// takeWhile
let mySeqLessThan10 = Seq.takeWhile (fun elem -> elem < 10) mySeq
mySeqLessThan10 |> printSeq

// skip
let mySeqSkipFirst5 = Seq.skip 5 mySeq
mySeqSkipFirst5 |> printSeq

// skipWhile
let mySeqSkipWhileLessThan10 = Seq.skipWhile (fun elem -> elem < 10) mySeq
mySeqSkipWhileLessThan10 |> printSeq

الإخراج هو كما يلي.

1 4 9 
36 49 64 81 100 
16 25 36 49 64 81 100 

Transforming تسلسلات

Seq.pairwise creates a جديد تسلسل in which successive عناصر of the إدخال تسلسل are grouped في tuples.

let seqPairwise = Seq.pairwise (seq { for i in 1 .. 10 -> i*i })
printSeq seqPairwise

printfn ""
let seqDelta = Seq.map (fun elem -> snd elem - fst elem) seqPairwise
printSeq seqDelta

let printList list1 = List.iter (printf "%A ") list1

Seq.windowed هو مثل Seq.pairwise، إلا أنه بدلاً من إنتاج سلسلة من المجموعات عن، فإنها تعطي سلسلة صفائف التي تحتوي على النسخ عناصر متجاورة ( نافذة ) من التسلسل. تعيين رقم متجاورة العناصر التي تريدها في كل الصفيف.

يلي تعليمات برمجية يوضح المثال استخدم Seq.windowed. في هذه الحالة رقم من العناصر في الإطار هو 3.

let seqNumbers = [ 1.0; 1.5; 2.0; 1.5; 1.0; 1.5 ] :> seq<float>
let seqWindows = Seq.windowed 3 seqNumbers
let seqMovingAverage = Seq.map Array.average seqWindows
printSeq seqNumbers
printfn ""
printSeq seqWindows
printfn ""
printSeq seqMovingAverage

الإخراج هو كما يلي.

1.0 1.5 2.0 1.5 1.0 1.5 

[|1.0; 1.5; 2.0|] [|1.5; 2.0; 1.5|] [|2.0; 1.5; 1.0|] [|1.5; 1.0; 1.5|] 

1.5 1.666666667 1.5 1.333333333 

تسلسلات مع متعددة العمليات

Seq.zip و Seq.zip3 أخذ تسلسلات أو ثلاث و إنتاج سلسلة من المجموعات عن. هذه دالات تشبه المطابقة دالات متوفرة ل قوائم . هناك هو لا يوجد وظائف المطابق لفصل تسلسلات واحد في تسلسلات أو أكثر. إذا كنت تحتاج هذه الوظيفة لسلسلة، تحويل التسلسل إلى القائمة و استخدم قائمة.unzip .

فرز والتجميع و مقارنة

فرز دالات معتمدة للقوائم أيضا العمل مع تسلسلات. يتضمن ذلك Seq.فرز و Seq.sortBy . يكرر هذه الوظائف من خلال الكل تسلسل.

يقارن اثنتين تسلسلات باستخدام Seq.compareWith دالة. دالة بمقارنة عناصر متتالية بدورها و يتوقف عندما يواجه الزوج أول غير متساوية. المساهمة أية عناصر إضافى إلى المقارنة.

يلي تعليمات برمجية يظهر استخدم Seq.compareWith.

// Compare two sequences.

let sequence1 = seq { 1 .. 10 }
let sequence2 = seq { 10 .. -1 .. 1 }

let compareSequences = Seq.compareWith (fun elem1 elem2 ->
    if elem1 > elem2 then 1
    elif elem1 < elem2 then -1
    else 0) 

let compareResult1 = compareSequences sequence1 sequence2

في تعليمات برمجية السابقة، العنصر أول فقط هو المحتسبة، واختبار، والنتيجة هو-1.

Seq.countBy تأخذ دالة التي تنشئ القيمة تدعي على المفتاح لكل عنصر. المفتاح هو التي تم إنشاؤها لكل عنصر عن طريق استدعاء th هو دالة تشغيل كل عنصر. Seq.countByثم إرجاع في السلسلة التي تحتوي على قيم المفاتيح، وعدد من العناصر التي تم إنشاؤها لكل القيمة من مفتاح.

let mySeq1 = seq { 1.. 100 }
let seqResult = Seq.countBy (fun elem -> if elem % 3 = 0 then 0
                                         elif elem % 3 = 1 then 1
                                         else 2) mySeq1

printSeq seqResult

الإخراج هو كما يلي.

(1, 34) (2, 33) (0, 33) 

يظهر إخراج السابقة تشير بوجود عناصر 34 الأصلي تسلسل إنتاجه على المفتاح 1، 33 القيم التي أنتجت قيم المفتاح 2، و 33 إنتاجه مفتاح 0.

يمكنك تجميع عناصر من سلسلة بواسطة استدعاء Seq.groupBy . Seq.groupByيأخذ تسلسل و دالة التي تنشئ مفتاحاً من على العنصر. دالة هو تنفيذها تشغيل كل عنصر في التسلسل. Seq.groupByبإرجاع سلسلة من المجموعات عن، الموقع يكون العنصر أول من كل المجموعة هو المفتاح و الثاني هو تسلسل عناصر التي ينتج عن ذلك المفتاح.

يلي تعليمات برمجية يظهر المثال استخدم Seq.groupByلتقسيم تسلسل الأرقام من 1 إلى 100 في ثلاث مجموعات التي تحتوي على المفتاح مميزة قيم 0، 1 و 2.

let sequence = seq { 1 .. 100 }
let sequences3 = Seq.groupBy (fun index ->
                                if (index % 3 = 0) then 0
                                  elif (index % 3 = 1) then 1
                                  else 2) sequence
sequences3 |> printSeq

الإخراج هو كما يلي.

(1, seq [1; 4; 7; 10; ...]) (2, seq [2; 5; 8; 11; ...]) (0, seq [3; 6; 9; 12; ...]) 

يمكنك إنشاء تسلسل على إزالة عناصر مكررة بواسطة استدعاء Seq.distinct . أو يمكنك استخدام Seq.distinctBy ، الذي يكون دالة إنشاء المفتاح إلى يمكن استدعاء في كل عنصر. تسلسل الناتج الذي يحتوي على عناصر ترتيب الأصلية التي تحتوي على مفاتيح فريدة؛ ويتم تجاهل العناصر اللاحقة التي تنتج المفتاح مكرر إلى عنصر سابق.

يلي تعليمات برمجية يوضح المثال استخدم Seq.distinct. Seq.distinctهو هو موضح بإنشاء تسلسلات التي تمثل ثنائي أرقام، وثم تظهر أن العناصر المميزة فقط هي 0 و 1.

let binary n =
    let rec generateBinary n =
        if (n / 2 = 0) then [n]
        else (n % 2) :: generateBinary (n / 2)
    generateBinary n |> List.rev |> Seq.ofList

printfn "%A" (binary 1024)

let resultSequence = Seq.distinct (binary 1024)
printfn "%A" resultSequence

يلي تعليمات برمجية يوضح Seq.distinctByقبل البدء بتسلسل التي تحتوي على أرقام سالبة وموجبة واستخدام دالة القيمة المطلقة كدالة-إنشاء المفتاح. تسلسل الناتج هو mهوsing موجبة بالجميع الأرقام التي تتطابق مع أرقام سالبة في التسلسل، لأنها تظهر سابقا في التسلسل الأرقام السالبة ولذلك محددة بدلاً من الأرقام الموجبة التي لها نفس القيمة المطلقة، أو المفتاح.

let inputSequence = { -5 .. 10 }
printSeq inputSequence
printfn ""
let seqDistinctAbsoluteValue = Seq.distinctBy (fun elem -> abs elem) inputSequence
seqDistinctAbsoluteValue |> printSeq

للقراءة فقط و المخزن مؤقتاً تتابعات

Seq.readonly بإنشاء نسخ للقراءة فقط من سلسلة. Seq.readonlyهو مفيداً عند وجود مجموعة القراءة والكتابة، مثل صفيفة، وكنت لا تريد تعديل المجموعة الأصلي. يمكن استخدام هذه دالة للاحتفاظ بتغليف بيانات. في مثال التعليمة البرمجية التالية، يتم تاريخ الإنشاء نوع الذي يحتوي على صفيفة. A خاصية exposes the صفيفة, but instead of returning an صفيفة, it إرجاع a تسلسل that هو تاريخ الإنشاء من the صفيفة بواسطة using Seq.readonly.

type ArrayContainer(start, finish) =
    let internalArray = [| start .. finish |]
    member this.RangeSeq = Seq.readonly internalArray
    member this.RangeArray = internalArray

let newArray = new ArrayContainer(1, 10)
let rangeSeq = newArray.RangeSeq
let rangeArray = newArray.RangeArray
// These lines produce an error: 
//let myArray = rangeSeq :> int array
//myArray.[0] <- 0
// The following line does not produce an error. 
// It does not preserve encapsulation.
rangeArray.[0] <- 0

Seq.ذاكرة تخزين مؤقت creates a stored الإصدار of a تسلسل. استخدم Seq.cache when you have multiple عمليات جزئية that استخدم a تسلسل, but you must make sure that each عنصر هو acted upon فقط واحد الوقت. When you have a تسلسل that هو being used بواسطة multiple عمليات جزئية, you can have واحد مؤشر ترابط that enumerates و computes the قيم for the الأصلي تسلسل, و remaining عمليات جزئية can استخدم the cached تسلسل.

Performing Computations تشغيل تسلسلات

Simple arithmetic العمليات are مثل those of lists, such كـ Seq.متوسط, Seq.جمع, Seq.averageBy, Seq.sumBy, و so تشغيل.

Seq.foldو Seq.reduce Seq.مسح ضوئي تشبه التابع لها دالات التي تتوفر للقوائم. تسلسلات يعتمد مجموعة فرعية من تباينات الكاملة من هذه الدالات التي تسرد الدعم. لمزيد من المعلومات والأمثلة ، انظرقوائم (F#) .

راجع أيضًا:

المرجع

IEnumerable<T>

موارد أخرى

مرجع لغة ب #

أنواع ب #