Diziler

Dizi, tek bir türün hepsinde yer alan mantıksal bir öğe dizisidir. Diziler özellikle büyük, sıralı bir veri koleksiyonunuz olduğunda ama her zaman tüm öğeleri kullanmayı beklemeyebilirsiniz. Tek tek dizi öğeleri yalnızca gerekli olarak hesaplanır, bu nedenle bir dizi tüm öğelerin kullanılmamış olduğu durumlarda bir listeden daha iyi performans sağlar. Diziler, için diğer seq<'T> ad olan türüyle temsil IEnumerable<T> eder. Bu nedenle, arabirimi uygulayan herhangi bir .NET IEnumerable<T> türü bir dizi olarak kullanılabilir. Seq modülü, dizileri içeren işlemeler için destek sağlar.

Sıra İfadeleri

Sıra ifadesi, bir dizi olarak değerlendirilen bir ifadedir. Sıra ifadeleri bir dizi biçime sahip olabilir. 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. İki çift dönem arasında bir artış (veya azaltma) da belirtsiniz. Örneğin, aşağıdaki kod 10'ların katlarını oluşturur.

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

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

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

Önceki örnek, değeri -> sıranın bir parçası olacak bir ifade belirtmenize olanak sağlayan işleci kullanır. yalnızca bunu izleyen -> kodun her parçası bir değer döndürse kullanabilirsiniz.

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

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 üretir. İlk ifadenin for do belirtilmelidir.

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

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

Dizide if kullanılan ifade bir filtredir. Örneğin, türünde bir işlevine sahip olduğunu varsayarak, yalnızca asal sayılardan bir dizi oluşturmak isprime int -> bool için sırayı aşağıdaki gibi oluşturun.

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

Daha önce belirtildiği do gibi, ile birlikte giden bir else dal olduğundan burada if gereklidir. kullanmayı denersanız, tüm dalların değer iade -> olmadığını söyleyen bir hata alırsınız.

yield! anahtar sözcüğü

Bazen, bir öğe dizisini başka bir diziye dahil etmek istediğiniz olabilir. Bir diziyi başka bir diziye dahil etmek için anahtar sözcüğünü yield! kullanabilirsiniz:

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

Bir diğer düşünce yolu yield! da bir iç diziyi düzdür ve ardından bunu içeren diziye dahil eder.

bir yield! ifadede kullanılırken, diğer tüm tek değerlerin anahtar sözcüğünü yield kullanması gerekir:

// 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 için değerinden x değerine kadar olan tüm değerlere 1 ek olarak değerini x x üretir.

Örnekler

İlk örnek, dizi oluşturmak için yineleme, filtre ve verim içeren bir dizi ifadesi kullanır. Bu kod konsola 1 ile 100 arasında bir asal sayı dizisi 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 bir çiftlerden 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 yield! tek bir son dizide birleştirmek için kullanımını gösteriyor. Bu durumda, ikili bir ağaçtaki her alt ağacın dizileri, son sırayı üretmek için özyinelemeli bir işlevde bir oluşturulur.

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

Diziler listeyle aynı işlevlerin birçoğuna sahiptir. Diziler, anahtar oluşturma işlevlerini kullanarak gruplama ve sayma gibi işlemleri de destekler. Diziler ayrıca alt dizileri ayıklamak için daha çeşitli işlevleri destekler.

Listeler, diziler, kümeler ve eşlemeler gibi birçok veri türü numaralanabilir koleksiyonlar olduğundan örtülü olarak sıralar. Bağımsız değişken olarak bir dizi alan işlev, uygulayan herhangi bir .NET veri türüne ek olarak ortak F# veri türlerinden herhangi biri ile System.Collections.Generic.IEnumerable<'T> çalışır. Bunu, bir listeyi bağımsız değişken olarak alan ve yalnızca liste ala bir işlevle karşıtlıklı olarak kullanın. türü seq<'T> için bir tür kısaltmasıdır. IEnumerable<'T> Bu, F# içinde diziler, listeler, kümeler ve eşlemeler içeren ve ayrıca çoğu .NET koleksiyon türünün türüyle uyumlu olduğu ve bir sıranın beklendiği her yerde kullanılamayacak şekilde geneli uygulayan herhangi bir türün olduğu anlamına System.Collections.Generic.IEnumerable<'T> seq gelir.

Modül İşlevleri

FSharp.Collections ad alanının Seq modülü, dizilerle çalışmak için işlevler içerir. Bu işlevler listelerle, dizilerle, eşlemelerle ve kümelerle de çalışır çünkü bu türlerin hepsi numaralanabilir ve bu nedenle dizi olarak işlenebilir.

Dizi Oluşturma

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

Seq.emptykullanarak boş bir dizi oluşturabilir veya Seq.singletonkullanarak yalnızca bir belirtilen öğe dizisi oluşturabilirsiniz.

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

Seq.init'i kullanarak, öğeleri sizin oluşturduğunuz bir işlev kullanılarak oluşturulan bir dizi oluşturabilirsiniz. Ayrıca, dizi için bir boyut sağlar. Bu işlev List.initişlevine benzer ancak siz dizide tekrarılana kadar öğelerin oluşturulmaz. Aşağıdaki kod, kullanımını Seq.init göstermektedir.

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

Çıktı şu şekildedir:

0 10 20 30 40

Seq.ofArray ve Seq.ofList< İşlevi'>kullanarak dizilerden ve listelerden diziler oluşturabilirsiniz. Ancak, bir dönüştürme işleci kullanarak dizileri ve listeleri dizilere de dönüştür edebilirsiniz. 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 gibi zayıf türe sahip bir koleksiyondan bir dizi System.Collections oluşturabilirsiniz. Bu tür zayıf türdeki koleksiyonlar öğe türüne sahiptir ve genel System.Object olmayan tür kullanılarak System.Collections.Generic.IEnumerable&#96;1 numaralandı. Aşağıdaki kod, bir diziye Seq.cast dönüştürmek için System.Collections.ArrayList kullanımını göstermektedir.

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, öğenin dizininden her öğeyi oluşturan bir işlev sağlar. Yavaş değerlendirme nedeniyle sonsuz diziler mümkündür; öğeleri, belirttiğiniz işlevi çağırarak oluşturulur. Aşağıdaki kod örneği, kayan nokta sayılarının sonsuz bir dizisini oluşturur; bu örnekte, sonraki tamsayıların karelerinin karşılıklı serisi.

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 hesaplama işlevinden bir dizi üretir ve dizideki sonraki her öğeyi üretmek için bu diziyi dönüştürer. Durum yalnızca her öğeyi hesaplamak için kullanılan bir değerdir ve her öğe hesaplandı olarak değişebilir. için ikinci bağımsız Seq.unfold değişken, diziyi 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 diziyi sonlandırmaya olanak None sağlar. Aşağıdaki kod, bir işlem tarafından oluşturulan seq1 ve fib dizilerinin iki örneği unfold gösterir. İlki olan seq1 , 20'ye kadar sayıya sahip basit bir dizidir. İkincisi, fib , unfold Fibonacci dizisini hesaplamak için kullanır. Fibonacci dizideki her öğe önceki iki Fibonacci saylarının toplamı olduğundan, durum değeri dizideki önceki iki sayıdan oluşan bir tuple'dır. İlk değer, (1,1) dizide yer alan ilk iki sayıdır.

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 =
    (1, 1) // Initial state
    |> Seq.unfold (fun state ->
        if (snd state > 1000) then
            None
        else
            Some(fst state + snd state, (snd state, fst state + snd 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.

2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597

Aşağıdaki kod, sonsuz dizilerin değerlerini oluşturmak ve hesaplamak için burada açıklanan dizi modülü işlevlerinin çoğunu kullanan bir örnektir. Kodun çalışması 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

Diziler listelerle kullanılabilen işlevleri destekler: Seq.exists, Seq.exists2, Seq.find, Seq.findIndex, Seq.pick, Seq.tryFindve Seq.tryFindIndex. Diziler için kullanılabilen bu işlevlerin sürümleri, sırayı yalnızca aranacak öğeye kadar değerlendirir. Örnekler için bkz. Listeler.

Alt Sıklıkları Alma

Seq.filter ve Seq.choose, listeler için kullanılabilen ilgili işlevlere benzer, ancak sıralama öğeleri değerlendirilene kadar filtreleme ve seçmenin oluşmaz.

Seq.truncate başka bir diziden bir dizi oluşturur, ancak diziyi belirtilen sayıda öğeyle sınırlar. Seq.take, bir dizinin başı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.InvalidOperationException atar. ve arasındaki Seq.take Seq.truncate fark, öğe sayısı belirttiğiniz sayıdan daha Seq.truncate azsa hata üretmez.

Aşağıdaki kod, ve arasındaki ve farklarını Seq.truncate Seq.take 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 çıktı 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.takeWhileişlevini kullanarak bir önkate işlevi (Boole işlevi) belirtebilirsiniz ve özgün sıranın bu öğelerinden başka bir diziden bir dizi oluşturabilirsiniz. Ancak, bunun için, predicate döndüren ilk öğeden önce true dur. false Seq.skip, başka bir sıranın ilk öğelerinin belirtilen sayıda atlayıp kalan öğeleri döndüren bir dizi döndürür. Seq.skipWhile, başka bir sıranın ilk öğelerini atlar bir dizi döndürür. Bunun için, predicate işlevi döndüren ilk öğeyle başlayarak kalan öğeleri true false döndürür.

Aşağıdaki kod örneği , ve arasındaki ve farklarını Seq.takeWhile Seq.skip Seq.skipWhile göstermektedir.

// 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 sonraki öğelerinin gruplara gruplandır olduğu 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 olur, ancak bir dizi dizisini üretmek yerine, diziden bitişik öğelerin Seq.pairwise kopyalarını (bir pencere) içeren bir dizi üretir. Her dizide istediğiniz bitişik öğe sayısını belirtirsiniz.

Aşağıdaki kod örneği kullanımını Seq.windowed gösteriyor. Bu durumda pencere içinde öğelerin sayısı 3'tir. Örnekte, printSeq önceki kod örneğinde tanımlanan kullanır.

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 Dizili İşlemler

Seq.zip ve Seq.zip3 iki veya üç sıra alır ve bir dizi dizisini üretir. Bu işlevler, listeleri için kullanılabilen ilgili işlevlere benzer. Bir diziyi iki veya daha fazla diziye ayırmak için karşılık gelen bir işlev yoktur. Bir dizi için bu işleve ihtiyacınız varsa, sırayı bir listeye dönüştürin ve List.unzip kullanın.

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

Listeler için desteklenen sıralama işlevleri de dizilerle çalışır. Buna Seq.sort ve Seq.sortBy dahildir. Bu işlevler, tüm dizide devam eder.

Seq.compareWith işlevini kullanarak iki diziyi karşılaştırıldığında. işlevi, arka sıra gelen öğeleri karşılar ve ilk eşit olmayan çiftle karşılaştığında durur. Başka hiçbir öğe karşılaştırmaya katkıda bulunan bir şey değildir.

Aşağıdaki kod, kullanımını Seq.compareWith gö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 incelendi 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 dizi ve anahtarın her bir değerini oluşturan öğe 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ış, özgün dizide 1 anahtarını üreten 34 öğe, 2 anahtarını üreten 33 değer ve 0 anahtarını üreten 33 değer olduğunu gösterir.

Seq.groupBy'yi çağırarak bir dizinin öğelerini gruplayın. Seq.groupBy bir dizi ve bir öğeden anahtar oluşturan bir işlev alır. İşlev, dizideki her öğede yürütülür. Seq.groupBy , her bir tuple'ın ilk öğesinin anahtar, ikinci öğenin ise bu anahtarı üreten öğelerin dizisi olduğu bir dizisini döndürür.

Aşağıdaki kod örneği, 1'den 100'e kadar olan sayı dizisini 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ğırarak yinelenen öğeleri ortadan kaldıran bir dizi oluşturabilirsiniz. Veya seq.distinctBy işlevini kullanabilirsiniz.Bu işlev, her öğede çağrılmayacak bir anahtar oluşturma işlevi alır. Sonuçta elde edilen dizi, benzersiz anahtarlara sahip özgün dizi öğelerini içerir; önceki bir öğeye yinelenen anahtar üreten sonraki öğeler atılır.

Aşağıdaki kod örneği kullanımını Seq.distinct göstermektedir. Seq.distinct , ikili sayıları temsil eden diziler üreterek ve ardından tek ayrı öğelerin 0 ve 1 olduğunu göstererek gösterebilirsiniz.

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şlayarak ve anahtar oluşturma işlevi olarak mutlak değer Seq.distinctBy işlevini kullanarak gösterir. Sonuçta elde edilen dizide, dizide negatif sayılara karşılık gelen tüm pozitif sayılar eksiktir çünkü negatif sayılar dizide daha önce görünür ve bu nedenle aynı mutlak değere veya anahtara sahip pozitif sayılar yerine seçilir.

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ış Diziler

Seq.readonly, bir sıranın salt okunur bir kopyasını oluşturur. Seq.readonly , dizi gibi bir okuma-yazma koleksiyonunuz olduğunda ve özgün koleksiyonu değiştirmek istemiyorken yararlıdır. Bu işlev, veri kapsüllemesi korumak için kullanılabilir. Aşağıdaki kod örneğinde, dizi içeren bir tür oluşturulur. Bir özellik diziyi gösterir, ancak bir diziyi döndürerek değil, kullanılarak diziden oluşturulan bir dizi Seq.readonly 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 sıranın depolanmış bir sürümünü oluşturur. Bir sıranın yeniden değerlendirilmesini önlemek için veya bir dizi kullanan birden çok iş parçacığına sahipken kullanın, ancak her öğenin yalnızca bir kez üzerinde eyleme Seq.cache geçirilene emin olun. Birden çok iş parçacığı tarafından kullanılan bir diziniz olduğunda, özgün dizi için değerleri numaralandıran ve hesap eden bir iş parçacığına sahip 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.sumByve benzerleri gibi listelerdendir.

Seq.fold, Seq.reduceve Seq.scan, listeler için kullanılabilen işlevlere benzer. Diziler, bu işlevlerin tam çeşitlemelerinin bir alt kümesini destekler. Daha fazla bilgi ve örnekler için bkz. Listeler.

Ayrıca bkz.