Dilimler

Bu makalede, mevcut F# türlerinden dilim alma ve kendi dilimlerinizi tanımlama işlemleri açıklanmaktadır.

F# dilinde dilim, herhangi bir veri türünün alt kümesidir. Dilimler dizin oluşturuculara benzer, ancak temel alınan veri yapısından tek bir değer vermek yerine birden çok değer verir. Dilimler, bir veri türündeki .. belirtilen dizin aralığını seçmek için işleç söz dizimini kullanır. Daha fazla bilgi için döngü ifadesi başvuru makalesine bakın.

F# şu anda dizeleri, listeleri, dizileri ve çok boyutlu (2B, 3B, 4B) dizileri dilimleme için iç desteğe sahiptir. Dilimleme en yaygın olarak F# dizileri ve listeleriyle kullanılır. Tür tanımınızda veya kapsam içi tür uzantısında yöntemini kullanarak GetSlice özel veri türlerinize dilimleme ekleyebilirsiniz.

F# listelerini ve dizilerini dilimleme

Dilimlenmiş en yaygın veri türleri F# listeleri ve dizileridir. Aşağıdaki örnekte listelerin nasıl dilimlenmiş olduğu gösterilmektedir:

// Generate a list of 100 integers
let fullList = [ 1 .. 100 ]

// Create a slice from indices 1-5 (inclusive)
let smallSlice = fullList[1..5]
printfn $"Small slice: {smallSlice}"

// Create a slice from the beginning to index 5 (inclusive)
let unboundedBeginning = fullList[..5]
printfn $"Unbounded beginning slice: {unboundedBeginning}"

// Create a slice from an index to the end of the list
let unboundedEnd = fullList[94..]
printfn $"Unbounded end slice: {unboundedEnd}"

Dizileri dilimleme, dilimleme listeleri gibidir:

// Generate an array of 100 integers
let fullArray = [| 1 .. 100 |]

// Create a slice from indices 1-5 (inclusive)
let smallSlice = fullArray[1..5]
printfn $"Small slice: {smallSlice}"

// Create a slice from the beginning to index 5 (inclusive)
let unboundedBeginning = fullArray[..5]
printfn $"Unbounded beginning slice: {unboundedBeginning}"

// Create a slice from an index to the end of the list
let unboundedEnd = fullArray[94..]
printfn $"Unbounded end slice: {unboundedEnd}"

F# 6'nın öncesinde dilimleme, ek .ile söz dizimini expr.[start..finish] kullanıyordu. Seçerseniz, bu söz dizimlerini kullanmaya devam edebilirsiniz. Daha fazla bilgi için bkz . RFC FS-1110.

Çok boyutlu dizileri dilimleme

F# F# çekirdek kitaplığındaki çok boyutlu dizileri destekler. Tek boyutlu dizilerde olduğu gibi, çok boyutlu dizi dilimleri de yararlı olabilir. Ancak, ek boyutların tanıtılması, belirli satır ve sütunların dilimlerini alabilmeniz için biraz farklı bir söz dizimi gerektirir.

Aşağıdaki örneklerde bir 2B dizinin nasıl dilimlenmiş olduğu gösterilmektedir:

// Generate a 3x3 2D matrix
let A = array2D [[1;2;3];[4;5;6];[7;8;9]]
printfn $"Full matrix:\n {A}"

// Take the first row
let row0 = A[0,*]
printfn $"{row0}"

// Take the first column
let col0 = A[*,0]
printfn $"{col0}"

// Take all rows but only two columns
let subA = A[*,0..1]
printfn $"{subA}"

// Take two rows and all columns
let subA' = A[0..1,*]
printfn $"{subA}"

// Slice a 2x2 matrix out of the full 3x3 matrix
let twoByTwo = A[0..1,0..1]
printfn $"{twoByTwo}"

Diğer veri yapıları için dilimleri tanımlama

F# çekirdek kitaplığı sınırlı bir tür kümesi için dilimleri tanımlar. Daha fazla veri türü için dilim tanımlamak isterseniz, bunu tür tanımının kendisinde veya bir tür uzantısında yapabilirsiniz.

Örneğin, uygun veri işlemeye olanak sağlamak için sınıfı için ArraySegment<T> dilimleri şu şekilde tanımlayabilirsiniz:

open System

type ArraySegment<'TItem> with
    member segment.GetSlice(start, finish) =
        let start = defaultArg start 0
        let finish = defaultArg finish segment.Count
        ArraySegment(segment.Array, segment.Offset + start, finish - start)

let arr = ArraySegment [| 1 .. 10 |]
let slice = arr[2..5] //[ 3; 4; 5]

ve ReadOnlySpan<T> türlerini kullanan Span<T> başka bir örnek:

open System

type ReadOnlySpan<'T> with
    member sp.GetSlice(startIdx, endIdx) =
        let s = defaultArg startIdx 0
        let e = defaultArg endIdx sp.Length
        sp.Slice(s, e - s)

type Span<'T> with
    member sp.GetSlice(startIdx, endIdx) =
        let s = defaultArg startIdx 0
        let e = defaultArg endIdx sp.Length
        sp.Slice(s, e - s)

let printSpan (sp: Span<int>) =
    let arr = sp.ToArray()
    printfn $"{arr}"

let sp = [| 1; 2; 3; 4; 5 |].AsSpan()
printSpan sp[0..] // [|1; 2; 3; 4; 5|]
printSpan sp[..5] // [|1; 2; 3; 4; 5|]
printSpan sp[0..3] // [|1; 2; 3|]
printSpan sp[1..3] // |2; 3|]

Yerleşik F# dilimleri bitiş-dahil

F# içindeki tüm iç dilimler bitiş dahil; yani, üst sınır dilime dahil edilir. Başlangıç dizini ve bitiş dizini x olan belirli bir dilim için, sonuçta elde edilen dilim y. değeri içerir.y

// Define a new list
let xs = [1 .. 10]

printfn $"{xs[2..5]}" // Includes the 5th index

Yerleşik F# boş dilimleri

F# listeleri, diziler, diziler, dizeler, çok boyutlu (2B, 3B, 4B) dizilerin tümü, söz dizimi var olmayan bir dilim üretebiliyorsa boş bir dilim oluşturur.

Aşağıdaki örneği inceleyin:

let l = [ 1..10 ]
let a = [| 1..10 |]
let s = "hello!"

let emptyList = l[-2..(-1)]
let emptyArray = a[-2..(-1)]
let emptyString = s[-2..(-1)]

Önemli

C# geliştiricileri bunların boş bir dilim oluşturmak yerine bir özel durum oluşturmasını bekleyebilir. Bu, boş koleksiyonların F# dilinde oluşturması temelinde oluşturulmuş bir tasarım kararıdır. Boş bir F# listesi başka bir F# listesiyle oluşturulabilir, var olan bir dizeye boş bir dize eklenebilir vb. Parametre olarak geçirilen değerlere dayalı dilimler almak ve boş bir koleksiyon oluşturarak sınırların > dışına dayanıklı olmak, F# kodunun bileşimine uygun olabilir.

3B ve 4B diziler için sabit dizin dilimleri

F# 3B ve 4B diziler için belirli bir dizini "düzeltebilir" ve bu dizin sabitlenmişken diğer boyutları dilimleyebilirsiniz.

Bunu göstermek için aşağıdaki 3B diziyi göz önünde bulundurun:

z = 0

x\y 0 1
0 0 1
1 2 3

z = 1

x\y 0 1
0 4 5
1 6 7

Diziden dilimi [| 4; 5 |] ayıklamak istiyorsanız sabit dizinli bir dilim kullanın.

let dim = 2
let m = Array3D.zeroCreate<int> dim dim dim

let mutable count = 0

for z in 0..dim-1 do
    for y in 0..dim-1 do
        for x in 0..dim-1 do
            m[x,y,z] <- count
            count <- count + 1

// Now let's get the [4;5] slice!
m[*, 0, 1]

Son satır, 3B dizinin ve z dizinlerini düzeltir y ve matrise karşılık gelen değerlerin geri kalanını x alır.

Ayrıca bkz.