Sıralamalar

Dizi, tek bir türün tümüne ait mantıksal bir öğe dizisidir. Diziler özellikle büyük, sıralı bir veri koleksiyonunuz olduğunda kullanışlıdır ancak tüm öğelerin kullanılmasını beklemeniz gerekmez. Tek tek sıra öğeleri yalnızca gerektiği gibi hesaplanır, bu nedenle bir dizi, tüm öğelerin kullanılmadığı durumlarda bir listeden daha iyi performans sağlayabilir. Sıralar türüyle seq<'T> temsil edilir ve bu türü için IEnumerable<T>bir diğer addır. Bu nedenle, arabirim uygulayan IEnumerable<T> herhangi bir .NET türü bir dizi olarak kullanılabilir. Seq modülü, dizileri içeren işlemeler için destek sağlar.

Sıralı İfadeler

Sıralı ifade , bir dizi olarak değerlendirilen bir ifadedir. Sıralı ifadeler bir dizi form alabilir. En basit form bir aralık belirtir. Örneğin, seq { 1 .. 5 } 1 ve 5 uç noktaları dahil olmak üzere beş öğe içeren bir dizi oluşturur. ayrıca iki çift nokta arasında bir artış (veya azaltma) belirtebilirsiniz. Örneğin, aşağıdaki kod 10'un katlarının sırasını oluşturur.

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

Sıra ifadeleri, dizinin değerlerini üreten F# ifadelerinden oluşur. Değerleri program aracılığıyla da oluşturabilirsiniz:

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

Önceki örnekte, değeri dizinin bir parçası olacak bir ifade belirtmenize olanak tanıyan işleci kullanılır -> . Yalnızca kodun onu izleyen her parçası bir değer döndürüyorsa kullanabilirsiniz -> .

Alternatif olarak, aşağıdaki isteğe bağlı yield olarak anahtar sözcüğünü belirtebilirsinizdo:

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

// The 'yield' is implicit and doesn't need to be specified in most cases.
seq {
    for i in 1..10 do
        i * i
}

Aşağıdaki kod, kılavuzu temsil eden bir dizide bir dizinle birlikte koordinat çiftlerinin listesini oluşturur. İlk for ifadenin do belirtilmesi gerektiğini unutmayın.

let (height, width) = (10, 10)

seq {
    for row in 0 .. width - 1 do
        for col in 0 .. height - 1 -> (row, col, row * width + col)
}

Bir if dizide kullanılan ifade bir filtredir. Örneğin, türünde int -> boolbir işleviniz isprime olduğunu varsayarak yalnızca asal sayılardan oluşan bir dizi oluşturmak için diziyi aşağıdaki gibi oluşturun.

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

Daha önce belirtildiği gibi, do ile birlikte ifgiden bir dal olmadığından else burada gereklidir. kullanmaya ->çalışırsanız, tüm dalların bir değer döndürmediğini belirten bir hata alırsınız.

yield! anahtar sözcüğü

Bazen, bir öğe dizisini başka bir diziye eklemek isteyebilirsiniz. Bir diziyi başka bir diziye eklemek için anahtar sözcüğünü yield! kullanmanız gerekir:

// Repeats '1 2 3 4 5' ten times
seq {
    for _ in 1..10 do
        yield! seq { 1; 2; 3; 4; 5}
}

Düşünmenin yield! bir diğer yolu da bir iç diziyi düzleştirmesi ve ardından bunu içeren diziye dahil olmasıdır.

yield! bir ifadede kullanıldığında, diğer tüm tek değerler şu yield anahtar sözcüğü kullanmalıdır:

// Combine repeated values with their values
seq {
    for x in 1..10 do
        yield x
        yield! seq { for i in 1..x -> i}
}

Önceki örnek, her xbiri için 'den 1 öğesine tüm değerlere x ek olarak değerini x üretir.

Örnekler

İlk örnekte bir dizi oluşturmak için yineleme, filtre ve verim içeren bir dizi ifadesi kullanılır. Bu kod, konsola 1 ile 100 arasında bir dizi asal sayı yazdırır.

// 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
                n
    }

for x in aSequence do
    printfn "%d" x

Aşağıdaki örnek, her biri iki faktörden ve üründen oluşan üç öğeden oluşan demetlerden oluşan bir çarpma tablosu oluşturur:

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

Aşağıdaki örnek, tek tek dizileri tek bir son dizide birleştirmek için uygulamasının kullanımını yield! gösterir. Bu durumda, bir ikili ağaçtaki her alt ağaç için sıralar, son diziyi üretmek için özyinelemeli bir işlevde birleştirilir.

// 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

Dizileri Kullanma

Sıralar, listelerle aynı işlevlerin çoğunu destekler. Sıralar, anahtar oluşturma işlevlerini kullanarak gruplandırma ve sayma gibi işlemleri de destekler. Diziler, alt dizileri ayıklamak için daha çeşitli işlevleri de destekler.

Listeler, diziler, kümeler ve haritalar gibi birçok veri türü, numaralandırılabilir koleksiyonlar olduğundan örtük olarak sıralardır. Bir diziyi bağımsız değişken olarak alan bir işlev, uygulayan System.Collections.Generic.IEnumerable<'T>herhangi bir .NET veri türüne ek olarak ortak F# veri türlerinden herhangi biriyle çalışır. Bunu, yalnızca liste alabilen bir listeyi bağımsız değişken olarak alan bir işlevle karşıtlık yapın. Tür seq<'T> , için IEnumerable<'T>bir tür kısaltmasıdır. Bu, F# dilinde diziler, listeler, kümeler ve eşlemeler içeren ve ayrıca çoğu .NET koleksiyon türünü içeren genel System.Collections.Generic.IEnumerable<'T>öğesini uygulayan herhangi bir türün seq türle uyumlu olduğu ve bir dizinin beklendiği her yerde kullanılabildiği anlamına gelir.

Modül İşlevleri

FSharp.Collections ad alanı içindeki Seq modülü, dizilerle çalışmaya yönelik işlevler içerir. Bu işlevler listeler, diziler, haritalar ve kümelerle de çalışır, çünkü bu türlerin tümü numaralandırılabilir ve bu nedenle dizi olarak işlenebilir.

Sıra oluşturma

Daha önce açıklandığı gibi sıra ifadelerini kullanarak veya belirli işlevleri kullanarak diziler oluşturabilirsiniz.

Seq.empty kullanarak boş bir sıra oluşturabilir veya Seq.singleton kullanarak yalnızca bir belirtilen öğeden oluşan bir dizi oluşturabilirsiniz.

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

Seq.init kullanarak, sağladığınız bir işlev kullanılarak öğelerin oluşturulduğu bir sıra oluşturabilirsiniz. Ayrıca sıra için bir boyut da sağlarsınız. Bu işlev aynı List.init gibidir, ancak siz diziyi yineleyene kadar öğelerin oluşturulmaması gerekir. Aşağıdaki kod, kullanımını Seq.initgösterir.

let seqFirst5MultiplesOf10 = Seq.init 5 (fun n -> n * 10)
Seq.iter (fun elem -> printf "%d " elem) seqFirst5MultiplesOf10

Çıkış şu şekildedir:

0 10 20 30 40

Seq.ofArray ve Seq.ofList'T<> İşlevini kullanarak dizilerden ve listelerden diziler oluşturabilirsiniz. Bununla birlikte, bir atama işleci kullanarak dizileri ve listeleri dizilere de dönüştürebilirsiniz. Her iki teknik de aşağıdaki kodda gösterilmiştir.

// 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.cast kullanarak, içinde tanımlananlar System.Collectionsgibi zayıf türe sahip bir koleksiyondan bir dizi oluşturabilirsiniz. Bu tür zayıf türdeki koleksiyonlar öğe türüne System.Object sahiptir ve genel System.Collections.Generic.IEnumerable&#96;1 olmayan tür kullanılarak numaralandırılır. Aşağıdaki kod, öğesinin Seq.cast bir System.Collections.ArrayList diziye dönüştürülmesini gösterir.

open System

let arr = ResizeArray<int>(10)

for i in 1 .. 10 do
    arr.Add(10)

let seqCast = Seq.cast arr

Seq.initInfinite işlevini kullanarak sonsuz diziler tanımlayabilirsiniz. Böyle bir dizi için, öğesinin dizininden her öğeyi oluşturan bir işlev sağlarsınız. Gecikmeli değerlendirme nedeniyle sonsuz diziler mümkündür; öğeleri, belirttiğiniz işlev çağrılarak gerektiği gibi oluşturulur. Aşağıdaki kod örneği, kayan nokta sayılarından oluşan sonsuz bir dizi oluşturur, bu örnekte ardışık tamsayı karelerinin değişen karşılıklı dizisini oluşturur.

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

printfn "%A" seqInfinite

Seq.unfold , bir durum alan bir hesaplama işlevinden bir dizi oluşturur ve bunu sırayla izleyen her öğeyi üretmek için dönüştürür. Durum yalnızca her öğeyi hesaplamak için kullanılan bir değerdir ve her öğe hesaplandıkça değişebilir. için ikinci bağımsız değişken Seq.unfold , sırayı başlatmak için kullanılan ilk değerdir. Seq.unfold durum için bir seçenek türü kullanır ve bu da değeri döndürerek None sırayı sonlandırmanıza olanak tanır. Aşağıdaki kod, seq1 bir unfold işlem tarafından oluşturulan ve fibdizilerinin iki örneğini gösterir. İlki, seq120'ye kadar sayı içeren basit bir dizidir. İkincisi, fibFibonacci dizisini hesaplamak için kullanır unfold . Fibonacci dizisindeki her öğe önceki iki Fibonacci numarasının toplamı olduğundan, durum değeri dizideki önceki iki sayıdan oluşan bir tanımlama grubudur. İlk değer, dizideki ilk iki sayıdır (0,1).

let seq1 =
    0 // Initial state
    |> Seq.unfold (fun state ->
        if (state > 20) then
            None
        else
            Some(state, state + 1))

printfn "The sequence seq1 contains numbers from 0 to 20."

for x in seq1 do
    printf "%d " x

let fib =
    (0, 1)
    |> Seq.unfold (fun state ->
        let cur, next = state
        if cur < 0 then  // overflow
            None
        else
            let next' = cur + next
            let state' = next, next'
            Some (cur, state') )

printfn "\nThe sequence fib contains Fibonacci numbers."
for x in fib do printf "%d " x

Çıktı aşağıdaki şekilde olacaktır:

The sequence seq1 contains numbers from 0 to 20.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

The sequence fib contains Fibonacci numbers.

0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 

Aşağıdaki kod, sonsuz dizilerin değerlerini oluşturmak ve hesaplamak için burada açıklanan dizi modülü işlevlerinin birçoğunun kullanıldığı bir örnektir. Kodun çalıştırılması birkaç dakika sürebilir.

// 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 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 =
    (0, 0.0)
    |>
    Seq.unfold (fun state ->
        let subtotal = snd state + Seq.item (fst state + 1) sequence
        if (fst state >= length) then
            None
        else
            Some(subtotal, (fst state + 1, subtotal)))

// 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)

Öğeleri Arama ve Bulma

Sıralar şu listelerle kullanılabilir işlevleri destekler: Seq.exists, Seq.exists2, Seq.find, Seq.findIndex, Seq.pick, Seq.tryFind ve Seq.tryFindIndex. Diziler için kullanılabilen bu işlevlerin sürümleri, yalnızca aranmakta olan öğeye kadar diziyi değerlendirir. Örnekler için bkz . Listeler.

Alt Dizileri Alma

Seq.filter ve Seq.choose , sıralama öğeleri değerlendirilene kadar filtreleme ve seçmenin gerçekleşmemesi dışında, listeler için kullanılabilen ilgili işlevlere benzer.

Seq.truncate başka bir diziden bir dizi oluşturur, ancak sırayı belirtilen sayıda öğeyle sınırlar. Seq.take , bir dizinin başlangıcından yalnızca belirtilen sayıda öğe içeren yeni bir dizi oluşturur. Dizide almak için belirttiğinizden daha az öğe varsa, Seq.take bir System.InvalidOperationExceptionoluşturur. ile Seq.truncate arasındaki Seq.take fark, Seq.truncate öğe sayısı belirttiğiniz sayıdan azsa hata üretmemesidir.

Aşağıdaki kod ile arasındaki Seq.truncateSeq.takeve farklarının davranışını gösterir.

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

Hata oluşmadan önce çıkış aşağıdaki gibidir.

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 kullanarak bir koşul işlevi (Boole işlevi) belirtebilir ve koşulun olduğu özgün dizinin bu öğelerinden oluşan başka bir diziden truebir dizi oluşturabilirsiniz, ancak koşulun döndürdüğü falseilk öğeden önce durdurabilirsiniz. Seq.skip , başka bir dizinin ilk öğelerinin belirtilen sayısını atlayan ve kalan öğeleri döndüren bir dizi döndürür. Seq.skipWhile , koşul döndürdüğü truesürece başka bir dizinin ilk öğelerini atlayan ve ardından koşulun döndürdüğü ilk öğeden başlayarak kalan öğeleri döndüren bir dizi döndürür false.

Aşağıdaki kod örneği , Seq.skipve Seq.skipWhilearasındaki Seq.takeWhileve arasındaki farkları gösterir.

// 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

Çıktı aşağıdaki gibidir:

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

Dizileri Dönüştürme

Seq.pairwise , giriş dizisinin ardışık öğelerinin tanımlama grupları halinde gruplandırıldığı yeni bir dizi oluşturur.

let printSeq seq1 = Seq.iter (printf "%A ") seq1; printfn ""
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

Seq.windowed gibi Seq.pairwiseolur, ancak bir demet dizisi oluşturmak yerine, diziden bitişik öğelerin (bir pencere) kopyalarını içeren dizi dizileri üretir. Her dizide istediğiniz bitişik öğelerin sayısını belirtirsiniz.

Aşağıdaki kod örneğinde kullanımı gösterilmektedir Seq.windowed. Bu durumda penceredeki öğelerin sayısı 3'tür. Örnekte, önceki kod örneğinde tanımlanan kullanılır printSeq.

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
printfn "Initial sequence: "
printSeq seqNumbers
printfn "\nWindows of length 3: "
printSeq seqWindows
printfn "\nMoving average: "
printSeq seqMovingAverage

Çıktı aşağıdaki gibidir:

İlk sıra:

1.0 1.5 2.0 1.5 1.0 1.5

Windows of length 3:
[|1.0; 1.5; 2.0|] [|1.5; 2.0; 1.5|] [|2.0; 1.5; 1.0|] [|1.5; 1.0; 1.5|]

Moving average:
1.5 1.666666667 1.5 1.333333333

Birden Çok Sıralı İşlemler

Seq.zip ve Seq.zip3 iki veya üç dizi alır ve bir demet dizisi oluşturur. Bu işlevler, listeler için kullanılabilen ilgili işlevler gibidir. Bir diziyi iki veya daha fazla diziye ayırmak için ilgili işlev yoktur. Bir dizi için bu işleve ihtiyacınız varsa, sırayı bir listeye dönüştürün ve List.unzip dosyasını kullanın.

Sıralama, Karşılaştırma ve Gruplandırma

Listeler için desteklenen sıralama işlevleri de dizilerle çalışır. Buna Seq.sort ve Seq.sortBy dahildir. Bu işlevler tüm dizi boyunca yinelenir.

Seq.compareWith işlevini kullanarak iki diziyi karşılaştırırsınız. İşlev sırayla ardışık öğeleri karşılaştırır ve ilk eşit olmayan çiftle karşılaştığında durur. Ek öğeler karşılaştırmaya katkıda bulunmaz.

Aşağıdaki kod, kullanımını Seq.compareWithgösterir.

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

// Compare two sequences element by element.
let compareSequences =
    Seq.compareWith (fun elem1 elem2 ->
        if elem1 > elem2 then 1
        elif elem1 < elem2 then -1
        else 0)

let compareResult1 = compareSequences sequence1 sequence2
match compareResult1 with
| 1 -> printfn "Sequence1 is greater than sequence2."
| -1 -> printfn "Sequence1 is less than sequence2."
| 0 -> printfn "Sequence1 is equal to sequence2."
| _ -> failwith("Invalid comparison result.")

Önceki kodda yalnızca ilk öğe hesaplanır ve inceler ve sonuç -1 olur.

Seq.countBy, her öğe için anahtar adlı bir değer oluşturan bir işlev alır. Her öğede bu işlev çağrılarak her öğe için bir anahtar oluşturulur. Seq.countBy ardından anahtar değerlerini içeren bir sıra ve anahtarın her değerini oluşturan öğe sayısının sayısını döndürür.

let mySeq1 = seq { 1.. 100 }

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

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

printSeq seqResult

Çıktı aşağıdaki gibidir:

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

Önceki çıkışta özgün dizinin 1 anahtarını üreten 34 öğesi, 2 anahtarını üreten 33 değer ve 0 anahtarını oluşturan 33 değer olduğu gösterilmiştir.

Seq.groupBy çağırarak bir dizinin öğelerini gruplandırabilirsiniz. Seq.groupBy bir dizi ve bir öğeden anahtar oluşturan bir işlev alır. İşlev, dizinin her öğesinde yürütülür. Seq.groupBy bir tanımlama grubu dizisi döndürür; burada her tanımlama grubunun ilk öğesi anahtar, ikincisi ise bu anahtarı üreten bir öğe dizisidir.

Aşağıdaki kod örneği, 1'den 100'e kadar olan sayıların sırasını 0, 1 ve 2 ayrı anahtar değerlerine sahip üç gruba bölmek için kullanımını Seq.groupBy gösterir.

let sequence = seq { 1 .. 100 }

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

let sequences3 =
    sequences
    |> Seq.groupBy (fun index ->
        if (index % 3 = 0) then 0
        elif (index % 3 = 1) then 1
        else 2)

sequences3 |> printSeq

Çıktı aşağıdaki gibidir:

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

Seq.distinct çağrısı yaparak yinelenen öğeleri ortadan kaldıran bir dizi oluşturabilirsiniz. İsterseniz, her öğede çağrılmak üzere bir anahtar oluşturma işlevi alan Seq.distinctBy de kullanabilirsiniz. Sonuçta elde edilen sıra, özgün dizinin benzersiz anahtarlara sahip öğelerini içerir; önceki bir öğe için yinelenen anahtar üreten sonraki öğeler atılır.

Aşağıdaki kod örneğinde kullanımı gösterilmektedir Seq.distinct. Seq.distinct , ikili sayıları temsil eden diziler oluşturularak ve ardından tek ayrı öğelerin 0 ve 1 olduğunu göstererek gösterilir.

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

Aşağıdaki kod, negatif ve pozitif sayılar içeren bir diziyle başlayıp anahtar oluşturma işlevi olarak mutlak değer işlevini kullanarak gösterir Seq.distinctBy . Negatif sayılar dizide daha önce göründüğünden ve bu nedenle aynı mutlak değere veya anahtara sahip pozitif sayılar yerine seçildiğinden, sonuçta elde edilen dizideki negatif sayılara karşılık gelen tüm pozitif sayılar eksiktir.

let inputSequence = { -5 .. 10 }
let printSeq seq1 = Seq.iter (printf "%A ") seq1

printfn "Original sequence: "
printSeq inputSequence

printfn "\nSequence with distinct absolute values: "
let seqDistinctAbsoluteValue = Seq.distinctBy (fun elem -> abs elem) inputSequence
printSeq seqDistinctAbsoluteValue

Salt Okunur ve Önbelleğe Alınmış Sıralar

Seq.readonly , bir dizinin salt okunur bir kopyasını oluşturur. Seq.readonly , dizi gibi bir okuma-yazma koleksiyonunuz olduğunda ve özgün koleksiyonu değiştirmek istemediğinizde kullanışlıdır. Bu işlev, veri kapsüllemesini korumak için kullanılabilir. Aşağıdaki kod örneğinde, dizi içeren bir tür oluşturulur. Bir özellik diziyi kullanıma sunar, ancak bir dizi döndürmek yerine kullanılarak Seq.readonlydiziden oluşturulan bir dizi döndürür.

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.cache bir dizinin depolanmış sürümünü oluşturur. Seq.cache Bir dizinin yeniden değerlendirilmesini önlemek için veya bir dizi kullanan birden çok iş parçacığınız olduğunda kullanın, ancak her öğenin yalnızca bir kez üzerinde işlem yapıldığından emin olmanız gerekir. Birden çok iş parçacığı tarafından kullanılan bir diziniz olduğunda, özgün dizinin değerlerini numaralandıran ve hesaplayan bir iş parçacığınız olabilir ve kalan iş parçacıkları önbelleğe alınmış diziyi kullanabilir.

Dizilerde HesaplamaLar Gerçekleştirme

Basit aritmetik işlemler Seq.average, Seq.sum, Seq.averageBy, Seq.sumBy vb. listelere benzer.

Seq.fold, Seq.reduce ve Seq.scan , listeler için kullanılabilen ilgili işlevler gibidir. Sıralar, bu işlevlerin destek listeleyen tam varyasyonlarının bir alt kümesini destekler. Daha fazla bilgi ve örnek için bkz . Listeler.

Ayrıca bkz.