Irisan
Artikel ini menjelaskan cara mengambil potongan dari jenis F# yang ada dan cara menentukan potongan Anda sendiri.
Di F#, potongan adalah subset dari jenis data apa pun. Potongan mirip dengan pengindeks, tetapi alih-alih menghasilkan satu nilai dari struktur data yang mendasar, mereka menghasilkan beberapa nilai. Potongan ..
menggunakan sintaks operator untuk memilih rentang indeks yang ditentukan dalam jenis data. Untuk informasi selengkapnya, lihat artikel referensi ekspresi perulangan.
F# saat ini memiliki dukungan intrinsik untuk memotong 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.
Memotong daftar dan array F#
Jenis data paling umum yang dipotong adalah daftar dan array F#. Contoh berikut menunjukkan cara memotong 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}"
Memotong array sama seperti memotong 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.
Memotong array multidimensi
F# mendukung array multidimensi di pustaka inti F#. Seperti halnya array satu dimensi, potongan array multidimensi juga dapat berguna. Namun, pengenalan dimensi tambahan mengamanatkan sintaks yang sedikit berbeda sehingga Anda dapat mengambil potongan baris dan kolom tertentu.
Contoh berikut menunjukkan cara memotong 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 potongan untuk struktur data lainnya
Pustaka inti F# mendefinisikan potongan untuk sekumpulan jenis terbatas. Jika Anda ingin menentukan potongan untuk lebih banyak jenis data, Anda dapat melakukannya baik dalam definisi jenis itu sendiri atau dalam ekstensi jenis.
Misalnya, berikut adalah bagaimana Anda dapat menentukan potongan 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 jenis Span<T> 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|]
Potongan F# bawaan bersifat inklusif akhir
Semua potongan intrinsik dalam F# bersifat inklusif akhir; artinya, batas atas disertakan dalam potongan. Untuk potongan tertentu dengan indeks x
awal dan indeks y
akhir, potongan yang dihasilkan akan menyertakan nilai yth.
// Define a new list
let xs = [1 .. 10]
printfn $"{xs[2..5]}" // Includes the 5th index
Potongan kosong F# bawaan
Daftar F#, array, urutan, string, array multidimensi (2D, 3D, 4D) semuanya akan menghasilkan potongan kosong jika sintaks dapat menghasilkan potongan 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 membuat pengecualian daripada menghasilkan potongan kosong. Ini adalah keputusan desain yang berakar pada fakta bahwa koleksi kosong disusun dalam F#. Daftar F# kosong dapat disusun dengan daftar F# lain, string kosong dapat ditambahkan ke string yang ada, dan sebagainya. Mengambil potongan bisa saja umum berdasarkan nilai yang diteruskan sebagai parameter, dan toleran terhadap out-of-bound > dengan menghasilkan koleksi kosong yang sesuai dengan sifat komposisi kode F#.
Potongan indeks tetap untuk array 3D dan 4D
Untuk array F# 3D dan 4D, Anda dapat "memperbaiki" indeks tertentu dan memotong dimensi lain dengan indeks tersebut tetap.
Untuk menggambarkan 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 potongan [| 4; 5 |]
dari array, gunakan potongan 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 indeks y
dan z
dari array 3D dan mengambil nilai lainnya x
yang sesuai dengan matriks.