Bagikan melalui


Slices

Artikel ini menjelaskan cara mengambil irisan dari jenis F# yang ada dan cara menentukan irisan Anda sendiri.

Di F#, iringan adalah subkumpulan dari jenis data apa pun. Irisan mirip dengan pengindeks, tetapi alih-alih menghasilkan satu nilai dari struktur data yang mendasar, mereka menghasilkan beberapa nilai. Irisan menggunakan .. sintaks operator untuk memilih rentang indeks tertentu dalam jenis data. Untuk informasi selengkapnya, lihat artikel referensi ekspresi perulangan.

F# saat ini memiliki dukungan intrinsik untuk mengiris string, daftar, array, dan array multidimensi (2D, 3D, 4D). Pemotongan paling umum digunakan dengan array dan daftar F#. Anda dapat menambahkan pemotongan ke jenis data kustom Anda dengan menggunakan GetSlice metode dalam definisi jenis Anda atau dalam ekstensi jenis dalam cakupan.

Mengiris daftar dan array F#

Jenis data paling umum yang diiris adalah daftar dan array F#. Contoh berikut menunjukkan cara menggoreng daftar:

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

Mengiris array sama seperti mengiris daftar:

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

Sebelum F# 6, pemotongan menggunakan sintaks expr.[start..finish] dengan tambahan .. Jika Anda memilih, Anda masih dapat menggunakan sintaks ini. Untuk informasi selengkapnya, lihat RFC FS-1110.

Mengiris array multidmensional

F# mendukung array multidirmani di pustaka inti F#. Seperti halnya array satu dimensi, irisan array multidirmansional juga dapat berguna. Namun, pengenalan dimensi tambahan mengamanatkan sintaksis yang sedikit berbeda sehingga Anda dapat mengambil irisan baris dan kolom tertentu.

Contoh berikut menunjukkan cara menggoreng array 2D:

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

Menentukan irisan untuk struktur data lainnya

Pustaka inti F# mendefinisikan irisan untuk sekumpulan jenis terbatas. Jika Anda ingin menentukan irisan untuk lebih banyak jenis data, Anda dapat melakukannya baik dalam definisi jenis itu sendiri atau dalam ekstensi jenis.

Misalnya, berikut adalah cara Anda dapat menentukan irisan untuk ArraySegment<T> kelas untuk memungkinkan manipulasi data yang nyaman:

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]

Contoh lain menggunakan Span<T> jenis dan ReadOnlySpan<T> :

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

Irisan F# bawaan bersifat end-inklusif

Semua irisan intrinsik dalam F# bersifat inklusif akhir; artinya, batas atas disertakan dalam ikatan. Untuk iringan tertentu dengan indeks x awal dan indeks yakhir , iringan yang dihasilkan akan menyertakan nilai yth .

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

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

Irisan kosong F# bawaan

Daftar F#, larik, urutan, string, array multidimensi (2D, 3D, 4D) semuanya akan menghasilkan ikatan kosong jika sintaks dapat menghasilkan ikatan yang tidak ada.

Pertimbangkan contoh berikut:

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

Penting

Pengembang C# mungkin mengharapkan ini untuk melemparkan pengecualian daripada menghasilkan ipotong kosong. Ini adalah keputusan desain yang berakar pada fakta bahwa koleksi kosong menyusun dalam F#. Daftar F# kosong dapat terdiri dengan daftar F# lain, string kosong dapat ditambahkan ke string yang ada, dan sebagainya. Biasanya mengambil irisan berdasarkan nilai yang diteruskan sebagai parameter, dan toleran terhadap out-of-bound dengan > menghasilkan koleksi kosong yang sesuai dengan sifat komposisi kode F#.

Irisan indeks tetap untuk array 3D dan 4D

Untuk array F# 3D dan 4D, Anda dapat "memperbaiki" indeks tertentu dan mengpotong dimensi lain dengan indeks tersebut tetap.

Untuk mengilustrasikan ini, pertimbangkan array 3D berikut:

z = 0

x\y 0 1
0 0 1
1 2 3

z = 1

x\y 0 1
0 4 5
1 6 7

Jika Anda ingin mengekstrak iringan [| 4; 5 |] dari array, gunakan iringan indeks tetap.

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]

Baris terakhir memperbaiki y indeks dan z array 3D dan mengambil nilai x lainnya yang sesuai dengan matriks.

Lihat juga