Diziler, tümü aynı türde olan sabit boyutlu, sıfır tabanlı, ardışık veri öğelerinin değiştirilebilir koleksiyonlarıdır.
Dizi oluşturma
Dizileri çeşitli yollarla oluşturabilirsiniz. Aşağıdaki örneklerde gösterildiği gibi ve |] arasında [| ardışık değerleri listeleyerek ve noktalı virgülle ayırarak küçük bir dizi oluşturabilirsiniz.
F#
let array1 = [| 1; 2; 3 |]
Ayrıca her öğeyi ayrı bir satıra koyabilirsiniz; bu durumda noktalı virgül ayırıcısı isteğe bağlıdır.
F#
let array1 =
[|
123
|]
Dizi öğelerinin türü, kullanılan değişmez değerlerden çıkarılır ve tutarlı olmalıdır.
F#
// This is an array of 3 integers.let array1 = [| 1; 2; 3 |]
// This is an array of a tuple of 3 integers.let array2 = [| 1, 2, 3 |]
3.0 bir float, 1 ve 2 tamsayılar olduğundan aşağıdaki kod hataya neden olur.
F#
// Causes an error. The 3.0 (float) cannot be converted to integer implicitly.// let array3 = [| 1; 2; 3.0 |]
Aşağıdaki kod da bir tanımlama grubu ve 3 bir tamsayı olduğundan 1,2 hataya neden olur.
F#
// Causes an error too. The 3 (integer) cannot be converted to tuple implicitly.// let array4 = [| 1, 2; 3 |]
Diziler oluşturmak için sıra ifadelerini de kullanabilirsiniz. Aşağıda, 1'den 10'a kadar tamsayı kareleri dizisi oluşturan bir örnek verilmiştir.
F#
let array3 = [| for i in1 .. 10 -> i * i |]
Tüm öğelerin sıfır olarak başlatıldığı bir dizi oluşturmak için kullanın Array.zeroCreate.
F#
let arrayOfTenZeroes : int array = Array.zeroCreate 10
Öğelere erişme
Köşeli ayraç ([ ve ]) kullanarak dizi öğelerine erişebilirsiniz. Özgün nokta söz dizimi (.[index]) hala desteklenmektedir ancak F# 6.0 itibarıyla artık önerilmez.
F#
array1[0]
Dizi dizinleri 0'da başlar.
Dizi öğelerine, dizinin bir alt alanını belirtmenize olanak tanıyan dilim gösterimini kullanarak da erişebilirsiniz. Dilim gösterimi örnekleri aşağıda verilmiştir.
F#
// Accesses elements from 0 to 2.
array1[0..2]
// Accesses elements from the beginning of the array to 2.
array1[..2]
// Accesses elements from 2 to the end of the array.
array1[2..]
Dilim gösterimi kullanıldığında, dizinin yeni bir kopyası oluşturulur.
Dizi türleri ve modülleri
Tüm F# dizilerinin türü .NET Framework türüdür System.Array. Bu nedenle, F# dizileri içinde System.Arraykullanılabilen tüm işlevleri destekler.
Modül, Array tek boyutlu dizilerdeki işlemleri destekler. , Array3Dve modülleri Array2Dsırasıyla iki, üç ve Array4D dört boyutlu dizilerdeki işlemleri destekleyen işlevler içerir. kullanarak System.Arraydörtten büyük derece dizileri oluşturabilirsiniz.
Basit işlevler
Array.get bir öğe alır. Array.length bir dizinin uzunluğunu verir. Array.set bir öğeyi belirtilen değere ayarlar. Aşağıdaki kod örneğinde bu işlevlerin kullanımı gösterilmektedir.
F#
let array1 = Array.create 10""for i in0 .. array1.Length - 1do
Array.set array1 i (i.ToString())
for i in0 .. array1.Length - 1do
printf "%s " (Array.get array1 i)
Çıktı aşağıdaki gibidir:
Console
0 1 2 3 4 5 6 7 8 9
Dizi oluşturan işlevler
Çeşitli işlevler, var olan bir diziye gerek kalmadan diziler oluşturur. Array.empty herhangi bir öğe içermeyen yeni bir dizi oluşturur. Array.create belirtilen boyutta bir dizi oluşturur ve tüm öğeleri sağlanan değerlere ayarlar. Array.init bir boyut ve öğeleri oluşturmak için bir işlev verilip bir dizi oluşturur. Array.zeroCreate tüm öğelerin dizinin türü için sıfır değerine başlatıldığı bir dizi oluşturur. Aşağıdaki kod bu işlevleri gösterir.
F#
let myEmptyArray = Array.empty
printfn "Length of empty array: %d" myEmptyArray.Length
printfn "Array of floats set to 5.0: %A" (Array.create 105.0)
printfn "Array of squares: %A" (Array.init 10 (fun index -> index * index))
let (myZeroArray : float array) = Array.zeroCreate 10
Çıktı aşağıdaki gibidir:
Console
Length of empty array: 0
Area of floats set to 5.0: [|5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0; 5.0|]
Array of squares: [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81|]
Array.copy var olan bir diziden kopyalanan öğeleri içeren yeni bir dizi oluşturur. Kopyanın sığ bir kopya olduğuna dikkat edin; başka bir deyişle öğe türü bir başvuru türüyse, temel alınan nesne değil yalnızca başvuru kopyalanır. Aşağıdaki kod örneği bunu gösterir.
F#
open System.Text
let firstArray : StringBuilder array = Array.init 3 (fun index -> new StringBuilder(""))
let secondArray = Array.copy firstArray
// Reset an element of the first array to a new value.
firstArray[0] <- new StringBuilder("Test1")
// Change an element of the first array.
firstArray[1].Insert(0, "Test2") |> ignore
printfn "%A" firstArray
printfn "%A" secondArray
Yukarıdaki kodun çıkışı aşağıdaki gibidir:
Console
[|Test1; Test2; |]
[|; Test2; |]
Test1 Dize yalnızca ilk dizide görünür çünkü yeni öğe oluşturma işlemi içindeki başvurunun firstArray üzerine yazar, ancak içinde hala bulunan secondArrayboş bir dizeye özgün başvuruyu etkilemez. Dize Test2 her iki dizide de görünür çünkü Insert türdeki System.Text.StringBuilder işlem her iki dizide de başvurulan temel nesneyi System.Text.StringBuilder etkiler.
Array.sub bir dizinin alt alanından yeni bir dizi oluşturur. Başlangıç dizinini ve uzunluğu sağlayarak alt düzenlemeyi belirtirsiniz. Aşağıdaki kod, kullanımını Array.subgösterir.
F#
let a1 = [| 0 .. 99 |]
let a2 = Array.sub a1 510
printfn "%A" a2
Çıktı, alt dizinin 5. öğede başladığını ve 10 öğe içerdiğini gösterir.
Console
[|5; 6; 7; 8; 9; 10; 11; 12; 13; 14|]
Array.append mevcut iki diziyi birleştirerek yeni bir dizi oluşturur.
Array.choose yeni bir diziye eklenecek dizi öğelerini seçer. Aşağıdaki kodda gösterilmektedir Array.choose. Dizinin öğe türünün seçenek türünde döndürülen değerin türüyle eşleşmesi gerekmediğini unutmayın. Bu örnekte öğe türü ve int seçeneği ise kayan nokta numarası olarak polinomsal işlevin elem*elem - 1sonucudur.
Array.collect mevcut bir dizinin her dizi öğesinde belirtilen bir işlevi çalıştırır ve ardından işlev tarafından oluşturulan öğeleri toplar ve bunları yeni bir dizide birleştirir. Aşağıdaki kodda gösterilmektedir Array.collect.
Array.filter Bir Boole koşul işlevi alır ve yalnızca koşulun true olduğu giriş dizisinden bu öğeleri içeren yeni bir dizi oluşturur. Aşağıdaki kodda gösterilmektedir Array.filter.
Çok boyutlu bir dizi oluşturulabilir, ancak çok boyutlu dizi değişmez değeri yazmak için söz dizimi yoktur. Dizi öğeleri dizi dizilerinden bir dizi oluşturmak için işlecini array2D kullanın. Diziler dizi veya liste değişmez değerleri olabilir. Örneğin, aşağıdaki kod iki boyutlu bir dizi oluşturur.
F#
let my2DArray = array2D [ [ 1; 0]; [0; 1] ]
İki boyutlu dizileri başlatmak için işlevini Array2D.init de kullanabilirsiniz ve benzer işlevler üç ve dört boyutlu diziler için kullanılabilir. Bu işlevler öğeleri oluşturmak için kullanılan bir işlev alır. bir işlev belirtmek yerine ilk değere ayarlanmış öğeleri içeren iki boyutlu bir dizi oluşturmak için, dört boyuta kadar diziler için de kullanılabilen işlevini kullanın Array2D.create . Aşağıdaki kod örneğinde önce istenen öğeleri içeren bir dizi dizisinin nasıl oluşturulacağı ve ardından istenen iki boyutlu diziyi oluşturmak için nasıl kullanıldığı Array2D.init gösterilmektedir.
F#
let arrayOfArrays = [| [| 1.0; 0.0 |]; [|0.0; 1.0 |] |]
let twoDimensionalArray = Array2D.init 22 (fun i j -> arrayOfArrays[i][j])
Sıra 4'e kadar olan diziler için dizi dizin oluşturma ve dilimleme söz dizimi desteklenir. Birden çok boyutta bir dizin belirttiğinizde, aşağıdaki kod örneğinde gösterildiği gibi dizinleri ayırmak için virgül kullanırsınız.
F#
twoDimensionalArray[0, 1] <- 1.0
İki boyutlu bir dizinin türü (örneğin , int[,]double[,]) olarak <type>[,] yazılır ve üç boyutlu bir dizinin türü, daha yüksek boyutlardaki diziler için gibi yazılır<type>[,,].
Çok boyutlu diziler için tek boyutlu diziler için kullanılabilen işlevlerin yalnızca bir alt kümesi de kullanılabilir.
Dizi dilimleme ve çok boyutlu diziler
İki boyutlu bir dizide (matris), aralıkları belirterek ve tam satırları veya sütunları belirtmek için joker karakter (*) kullanarak bir alt matris ayıklayabilirsiniz.
F#
// Get rows 1 to N from an NxM matrix (returns a matrix):
matrix[1.., *]
// Get rows 1 to 3 from a matrix (returns a matrix):
matrix[1..3, *]
// Get columns 1 to 3 from a matrix (returns a matrix):
matrix[*, 1..3]
// Get a 3x3 submatrix:
matrix[1..3, 1..3]
Çok boyutlu bir diziyi aynı veya daha düşük boyuttaki alt dizilere ayrıştırabilirsiniz. Örneğin, tek bir satır veya sütun belirterek matristen vektör elde edebilirsiniz.
F#
// Get row 3 from a matrix as a vector:
matrix[3, *]
// Get column 3 from a matrix as a vector:
matrix[*, 3]
Bu dilimleme söz dizimini, öğe erişim işleçlerini ve aşırı yüklenmiş GetSlice yöntemleri uygulayan türler için kullanabilirsiniz. Örneğin, aşağıdaki kod F# 2D dizisini sarmalayan, dizi dizin oluşturma desteği sağlamak üzere bir Item özelliği uygulayan ve üç sürümünü GetSliceuygulayan bir Matris türü oluşturur. Bu kodu matris türleriniz için şablon olarak kullanabilirseniz, bu bölümde açıklanan tüm dilimleme işlemlerini kullanabilirsiniz.
F#
typeMatrix<'T>(N: int, M: int) =
let internalArray = Array2D.zeroCreate<'T> N M
member this.Item
with get(a: int, b: int) = internalArray[a, b]
and set(a: int, b: int) (value:'T) = internalArray[a, b] <- value
member this.GetSlice(rowStart: int option, rowFinish : int option, colStart: int option, colFinish : int option) =
let rowStart =
match rowStart with
| Some(v) -> v
| None -> 0let rowFinish =
match rowFinish with
| Some(v) -> v
| None -> internalArray.GetLength(0) - 1let colStart =
match colStart with
| Some(v) -> v
| None -> 0let colFinish =
match colFinish with
| Some(v) -> v
| None -> internalArray.GetLength(1) - 1
internalArray[rowStart..rowFinish, colStart..colFinish]
member this.GetSlice(row: int, colStart: int option, colFinish: int option) =
let colStart =
match colStart with
| Some(v) -> v
| None -> 0let colFinish =
match colFinish with
| Some(v) -> v
| None -> internalArray.GetLength(1) - 1
internalArray[row, colStart..colFinish]
member this.GetSlice(rowStart: int option, rowFinish: int option, col: int) =
let rowStart =
match rowStart with
| Some(v) -> v
| None -> 0let rowFinish =
match rowFinish with
| Some(v) -> v
| None -> internalArray.GetLength(0) - 1
internalArray[rowStart..rowFinish, col]
module test =
let generateTestMatrix x y =
let matrix = new Matrix<float>(3, 3)
for i in0..2dofor j in0..2do
matrix[i, j] <- float(i) * x - float(j) * y
matrix
let test1 = generateTestMatrix 2.31.1let submatrix = test1[0..1, 0..1]
printfn $"{submatrix}"let firstRow = test1[0,*]
let secondRow = test1[1,*]
let firstCol = test1[*,0]
printfn $"{firstCol}"
Dizilerdeki Boole işlevleri
Sırasıyla bir veya iki dizideki işlevler Array.exists ve Array.exists2 test öğeleri. Bu işlevler bir test işlevi alır ve koşulu karşılayan bir öğe (veya öğesi Array.exists2çifti) varsa döndürürtrue.
Aşağıdaki kod ve Array.exists2kullanımını Array.exists gösterir. Bu örneklerde, yeni işlevler bağımsız değişkenlerden yalnızca biri ( bu durumlarda işlev bağımsız değişkeni) uygulanarak oluşturulur.
Benzer şekilde işlev Array.forall , her öğenin boole koşuluna uygun olup olmadığını belirlemek için bir diziyi test eder. Değişim Array.forall2 , eşit uzunlukta iki diziden oluşan öğeleri içeren bir Boole işlevi kullanarak aynı şeyi yapar. Aşağıdaki kodda bu işlevlerin kullanımı gösterilmektedir.
Aşağıdaki kod, hem mükemmel kare hem de mükemmel küp olan bir sayıyı bulmak için ve Array.findIndex kullanırArray.find.
F#
let arrayA = [| 2 .. 100 |]
let delta = 1.0e-10let isPerfectSquare (x:int) =
let y = sqrt (float x)
abs(y - round y) < delta
let isPerfectCube (x:int) =
let y = System.Math.Pow(float x, 1.0/3.0)
abs(y - round y) < delta
let element = Array.find (fun elem -> isPerfectSquare elem && isPerfectCube elem) arrayA
let index = Array.findIndex (fun elem -> isPerfectSquare elem && isPerfectCube elem) arrayA
printfn "The first element that is both a square and a cube is %d and its index is %d." element index
Çıktı aşağıdaki gibidir:
Console
The first element that is both a square and a cube is 64 and its index is 62.
Array.tryFind gibi Array.findolur, ancak sonucu bir seçenek türü olur ve öğe bulunamazsa döndürür None . Array.tryFind dizisinde Array.find eşleşen bir öğenin olup olmadığını bilmediğiniz durumlarda yerine kullanılmalıdır. Benzer şekilde, Array.tryFindIndex seçenek türünün dönüş değeri olması dışında benzerdir Array.findIndex . Öğe bulunmazsa seçeneği olur None.
Aşağıdaki kod, kullanımını Array.tryFindgösterir. Bu kod önceki koda bağlıdır.
F#
let delta = 1.0e-10let isPerfectSquare (x:int) =
let y = sqrt (float x)
abs(y - round y) < delta
let isPerfectCube (x:int) =
let y = System.Math.Pow(float x, 1.0/3.0)
abs(y - round y) < delta
let lookForCubeAndSquare array1 =
let result = Array.tryFind (fun elem -> isPerfectSquare elem && isPerfectCube elem) array1
match result with
| Some x -> printfn "Found an element: %d" x
| None -> printfn "Failed to find a matching element."
lookForCubeAndSquare [| 1 .. 10 |]
lookForCubeAndSquare [| 100 .. 1000 |]
lookForCubeAndSquare [| 2 .. 50 |]
Çıktı aşağıdaki gibidir:
Console
Found an element: 1
Found an element: 729
Failed to find a matching element.
Bir öğeyi bulmaya ek olarak dönüştürmeniz gerektiğinde kullanın Array.tryPick . Sonuç, işlevin dönüştürülen öğeyi seçenek değeri olarak döndürdüğü veya None böyle bir öğe bulunamazsa ilk öğesidir.
Aşağıdaki kod, kullanımını Array.tryPickgösterir. Bu durumda, bir lambda ifadesi yerine, kodu basitleştirmek için çeşitli yerel yardımcı işlevleri tanımlanır.
F#
let findPerfectSquareAndCube array1 =
let delta = 1.0e-10let isPerfectSquare (x:int) =
let y = sqrt (float x)
abs(y - round y) < delta
let isPerfectCube (x:int) =
let y = System.Math.Pow(float x, 1.0/3.0)
abs(y - round y) < delta
// intFunction : (float -> float) -> int -> int// Allows the use of a floating point function with integers.let intFunction function1 number = int (round (function1 (float number)))
let cubeRoot x = System.Math.Pow(x, 1.0/3.0)
// testElement: int -> (int * int * int) option// Test an element to see whether it is a perfect square and a perfect// cube, and, if so, return the element, square root, and cube root// as an option value. Otherwise, return None.let testElement elem =
if isPerfectSquare elem && isPerfectCube elem then
Some(elem, intFunction sqrt elem, intFunction cubeRoot elem)
else None
match Array.tryPick testElement array1 with
| Some (n, sqrt, cuberoot) -> printfn "Found an element %d with square root %d and cube root %d." n sqrt cuberoot
| None -> printfn "Did not find an element that is both a perfect square and a perfect cube."
findPerfectSquareAndCube [| 1 .. 10 |]
findPerfectSquareAndCube [| 2 .. 100 |]
findPerfectSquareAndCube [| 100 .. 1000 |]
findPerfectSquareAndCube [| 1000 .. 10000 |]
findPerfectSquareAndCube [| 2 .. 50 |]
Çıktı aşağıdaki gibidir:
Console
Found an element 1 with square root 1 and cube root 1.
Found an element 64 with square root 8 and cube root 4.
Found an element 729 with square root 27 and cube root 9.
Found an element 4096 with square root 64 and cube root 16.
Did not find an element that is both a perfect square and a perfect cube.
Dizilerde hesaplamalar gerçekleştirme
işlevi, Array.average dizideki her öğenin ortalamasını döndürür. Kayan nokta türlerini içeren ancak tamsayı türlerini içermeyen tamsayıya göre tamsayı bölmeyi destekleyen öğe türleriyle sınırlıdır. işlevi, Array.averageBy her öğede işlev çağırma sonuçlarının ortalamasını döndürür. İntegral türünde bir dizi için işlevini kullanabilir Array.averageBy ve işlevinin hesaplama için her öğeyi kayan nokta türüne dönüştürmesini sağlayabilirsiniz.
Öğe türü destekliyorsa en yüksek veya en düşük öğeyi almak için veya Array.min kullanınArray.max. Benzer şekilde ve Array.maxByArray.minBy önce bir işlevin yürütülmesine izin verin, belki de karşılaştırmayı destekleyen bir türe dönüştürün.
Array.sum bir dizinin öğelerini ekler ve Array.sumBy her öğedeki bir işlevi çağırır ve sonuçları bir araya getirir.
Dönüş değerlerini depolamadan dizideki her öğede bir işlev yürütmek için kullanın Array.iter. Eşit uzunlukta iki dizi içeren bir işlev için kullanın Array.iter2. İşlevin sonuçlarının bir dizisini de tutmanız gerekiyorsa, aynı anda iki dizi üzerinde çalışan veya Array.map2kullanınArray.map.
Hesaplamalar gerçekleştirmeye yönelik bu işlevler, Liste modülündeki aynı ada sahip işlevlere karşılık gelir. Kullanım örnekleri için bkz . Listeler.
Dizileri değiştirme
Array.set bir öğeyi belirtilen değere ayarlar. Array.fill bir dizideki öğe aralığını belirtilen bir değere ayarlar. Aşağıdaki kod bir örneği Array.fillsağlar.
Bir diziyi genel karşılaştırma işlevini kullanarak sıralamak için kullanın Array.sort . Anahtar üzerindeki genel karşılaştırma işlevini kullanarak sıralamak için anahtar olarak adlandırılan bir değer oluşturan bir işlev belirtmek için kullanınArray.sortBy. Özel bir karşılaştırma işlevi sağlamak istiyorsanız kullanın Array.sortWith . Array.sort, Array.sortByve Array.sortWith tümü sıralanmış diziyi yeni bir dizi olarak döndürür. , ve Array.sortInPlaceWith çeşitlemeleriArray.sortInPlaceArray.sortInPlaceBy, yeni bir dizi döndürmek yerine var olan diziyi değiştirir.
Diziler ve tanımlama kümeleri
Tanımlama grubu çiftlerinin dizilerini işlev Array.zip ve Array.unzip dönüştürme dizileri, dizi demetlerine dönüştürür ve tam tersi de geçerlidir. Array.zip3 ve Array.unzip3 üç öğeden oluşan demetlerle veya üç diziden oluşan demetlerle çalışmaları dışında benzerdir.
Dizilerdeki paralel hesaplamalar
Modül Array.Parallel , dizilerde paralel hesaplamalar gerçekleştirmeye yönelik işlevler içerir. Bu modül, .NET Framework'ün 4 sürümünden önceki sürümlerini hedefleyen uygulamalarda kullanılamaz.
Bu içeriğin kaynağı GitHub'da bulunabilir; burada ayrıca sorunları ve çekme isteklerini oluşturup gözden geçirebilirsiniz. Daha fazla bilgi için katkıda bulunan kılavuzumuzu inceleyin.
.NET geri bildirimi
.NET, açık kaynak bir projedir. Geri bildirim sağlamak için bir bağlantı seçin:
Diğer geliştiriciler ve uzmanlarla gerçek dünyadaki kullanım örneklerini temel alan ölçeklenebilir yapay zeka çözümleri oluşturmak için toplantı serisine katılın.