F # - Mảng

Mảng là tập hợp có kích thước cố định, dựa trên 0, có thể thay đổi của các phần tử dữ liệu liên tiếp có cùng kiểu.

Tạo Mảng

Bạn có thể tạo mảng bằng các cú pháp và cách khác nhau hoặc bằng cách sử dụng các hàm từ mô-đun Mảng. Trong phần này, chúng ta sẽ thảo luận về việc tạo mảng mà không cần sử dụng các hàm mô-đun.

Có ba cách cú pháp để tạo mảng không có hàm:

  • Bằng cách liệt kê các giá trị liên tiếp giữa [| và |] và được phân tách bằng dấu chấm phẩy.
  • Bằng cách đặt mỗi phần tử trên một dòng riêng biệt, trong trường hợp này, dấu phân tách bằng dấu chấm phẩy là tùy chọn.
  • Bằng cách sử dụng biểu thức trình tự.

Bạn có thể truy cập các phần tử của mảng bằng cách sử dụng toán tử dấu chấm (.) Và dấu ngoặc ([và]).

Ví dụ sau minh họa việc tạo mảng:

//using semicolon separator
let array1 = [| 1; 2; 3; 4; 5; 6 |]
for i in 0 .. array1.Length - 1 do
   printf "%d " array1.[i]
printfn" "

// without semicolon separator
let array2 =
   [|
      1
      2
      3
      4
      5
   |]
for i in 0 .. array2.Length - 1 do
   printf "%d " array2.[i]
printfn" "

//using sequence
let array3 = [| for i in 1 .. 10 -> i * i |]
for i in 0 .. array3.Length - 1 do
   printf "%d " array3.[i]
printfn" "

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

1 2 3 4 5 6
1 2 3 4 5
1 4 9 16 25 36 49 64 81 100

Các thao tác cơ bản trên mảng

Mô-đun thư viện Microsoft.FSharp.Collections.Array hỗ trợ các hoạt động trên mảng một chiều.

Bảng sau đây trình bày các thao tác cơ bản trên Mảng:

Giá trị Sự miêu tả
nối thêm: 'T [] →' T [] → 'T [] Tạo một mảng có chứa các phần tử của một mảng theo sau là các phần tử của mảng khác.
trung bình: ^ T [] → ^ T Trả về giá trị trung bình của các phần tử trong một mảng.
AverageBy: ('T → ^ U) →' T [] → ^ U Trả về giá trị trung bình của các phần tử được tạo bằng cách áp dụng một hàm cho từng phần tử của mảng.
blit: 'T [] → int →' T [] → int → int → đơn vị Đọc một loạt các phần tử từ một mảng và ghi chúng vào một mảng khác.
chọn: ('T → U option) →' T [] → 'U [] Áp dụng một hàm được cung cấp cho mỗi phần tử của mảng. Trả về một mảng chứa kết quả x cho mỗi phần tử mà hàm trả về Some (x).
thu thập: ('T →' U []) → T [] → 'U [] Áp dụng hàm đã cung cấp cho từng phần tử của mảng, nối kết quả và trả về mảng kết hợp.
concat: seq <'T []> →' T [] Tạo một mảng chứa các phần tử của mỗi chuỗi mảng được cung cấp.
sao chép: 'T →' T [] Tạo một mảng có chứa các phần tử của mảng được cung cấp.
tạo: int → 'T →' T [] Tạo một mảng có tất cả các phần tử ban đầu là giá trị được cung cấp.
trống: 'T [] Trả về một mảng trống của kiểu đã cho.
tồn tại: ('T → bool) →' T [] → bool Kiểm tra xem bất kỳ phần tử nào của mảng có thỏa mãn vị từ được cung cấp hay không.
tồn tại2: ('T1 →' T2 → bool) → 'T1 [] →' T2 [] → bool Kiểm tra xem có cặp phần tử tương ứng nào của hai mảng thỏa mãn điều kiện được cung cấp hay không.
điền: 'T [] → int → int →' T → đơn vị Điền vào một loạt các phần tử của một mảng với giá trị được cung cấp.
bộ lọc: ('T → bool) →' T [] → 'T [] Trả về một tập hợp chỉ chứa các phần tử của mảng được cung cấp mà điều kiện đã cung cấp trả về true.
tìm: ('T → bool) →' T [] → 'T Trả về phần tử đầu tiên mà hàm đã cung cấp trả về true. Tăng KeyNotFoundException nếu không có phần tử nào như vậy tồn tại.
findIndex: ('T → bool) →' T [] → int Trả về chỉ số của phần tử đầu tiên trong mảng thỏa mãn điều kiện đã cung cấp. Tăng KeyNotFoundException nếu không có phần tử nào thỏa mãn điều kiện.
gấp: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → 'T [] →' Trạng thái Áp dụng một hàm cho mỗi phần tử của một mảng, xâu chuỗi một đối số tích lũy thông qua tính toán. Nếu hàm đầu vào là f và các phần tử của mảng là i0 ... iN, hàm này tính f (... (fs i0) ...) iN.
fold2: ('Trạng thái →' T1 → 'T2 →' Trạng thái) → 'Trạng thái →' T1 [] → 'T2 [] →' Trạng thái Áp dụng một hàm cho các cặp phần tử từ hai mảng được cung cấp, từ trái sang phải, xâu chuỗi một đối số tích lũy thông qua tính toán. Hai mảng đầu vào phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
foldBack: ('T →' Trạng thái → 'Trạng thái) →' T [] → 'Trạng thái →' Trạng thái Áp dụng một hàm cho mỗi phần tử của một mảng, xâu chuỗi một đối số tích lũy thông qua tính toán. Nếu hàm đầu vào là f và các phần tử của mảng là i0 ... iN, hàm này tính f i0 (... (f iN s)).
foldBack2: ('T1 →' T2 → 'Trạng thái →' Trạng thái) → 'T1 [] →' T2 [] → 'Trạng thái →' Trạng thái Áp dụng một hàm cho các cặp phần tử từ hai mảng được cung cấp, từ phải sang trái, xâu chuỗi một đối số tích lũy thông qua tính toán. Hai mảng đầu vào phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
forall: ('T → bool) →' T [] → bool Kiểm tra xem tất cả các phần tử của một mảng có thỏa mãn điều kiện đã cung cấp hay không.
forall2: ('T1 →' T2 → bool) → 'T1 [] →' T2 [] → bool Kiểm tra xem tất cả các phần tử tương ứng của hai mảng được cung cấp có thỏa mãn điều kiện được cung cấp hay không.
lấy: 'T [] → int →' T Nhận một phần tử từ một mảng.
init: int → (int → 'T) →' T [] Sử dụng một hàm được cung cấp để tạo một mảng có thứ nguyên được cung cấp.
isEmpty: 'T [] → bool Kiểm tra xem một mảng có bất kỳ phần tử nào không.
iter: ('T → đơn vị) →' T [] → đơn vị Áp dụng hàm được cung cấp cho từng phần tử của mảng.
iter2: ('T1 →' T2 → đơn vị) → 'T1 [] →' T2 [] → đơn vị) Áp dụng hàm đã cung cấp cho một cặp phần tử từ các chỉ mục phù hợp trong hai mảng. Hai mảng phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
iteri: (int → 'T → đơn vị) →' T [] → đơn vị Áp dụng hàm được cung cấp cho từng phần tử của mảng. Số nguyên được truyền vào hàm cho biết chỉ số của phần tử.
iteri2: (int → 'T1 →' T2 → đơn vị) → 'T1 [] →' T2 [] → đơn vị Áp dụng hàm đã cung cấp cho một cặp phần tử từ các chỉ mục phù hợp trong hai mảng, đồng thời truyền chỉ mục của các phần tử. Hai mảng phải có cùng độ dài; nếu không, một ArgumentException được nâng lên.
chiều dài: 'T [] → int Trả về độ dài của một mảng. Thuộc tính Length cũng làm điều tương tự.
bản đồ: ('T →' U) → 'T [] →' U [] Tạo một mảng có các phần tử là kết quả của việc áp dụng hàm được cung cấp cho từng phần tử của một mảng được cung cấp.
map2: ('T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] Tạo một mảng có các phần tử là kết quả của việc áp dụng hàm được cung cấp cho các phần tử tương ứng của hai mảng được cung cấp. Hai mảng đầu vào phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
mapi: (int → 'T →' U) → 'T [] →' U [] Tạo một mảng có các phần tử là kết quả của việc áp dụng hàm được cung cấp cho từng phần tử của một mảng được cung cấp. Một chỉ số số nguyên được chuyển đến hàm cho biết chỉ số của phần tử đang được chuyển đổi.
mapi2: (int → 'T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] Tạo một mảng có các phần tử là kết quả của việc áp dụng hàm đã cung cấp cho các phần tử tương ứng của hai tập hợp theo cặp, đồng thời chuyển chỉ số của các phần tử. Hai mảng đầu vào phải có cùng độ dài; nếu không, ArgumentException được nâng lên.
tối đa: 'T [] →' T Trả về giá trị lớn nhất trong số tất cả các phần tử của một mảng. Các toán tử.max được sử dụng để so sánh các phần tử.
maxBy: ('T →' U) → 'T [] →' T Trả về phần tử lớn nhất trong số tất cả các phần tử của mảng, được so sánh qua Operator.max trên kết quả của hàm.
tối thiểu: ('T [] →' T Trả về phần tử nhỏ nhất trong số tất cả các phần tử của một mảng. Operator.min được sử dụng để so sánh các phần tử.
minBy: ('T →' U) → 'T [] →' T Trả về phần tử nhỏ nhất trong số tất cả các phần tử của một mảng. Operator.min được sử dụng để so sánh các phần tử.
ofList: 'T list →' T [] Tạo một mảng từ danh sách được cung cấp.
ofSeq: seq <'T> →' T [] Tạo một mảng từ đối tượng có thể liệt kê được cung cấp.
phân vùng: ('T → bool) →' T [] → 'T [] *' T [] Tách một mảng thành hai mảng, một mảng chứa các phần tử mà điều kiện đã cung cấp trả về true, và cái kia chứa những thứ mà nó trả về false.
hoán vị: (int → int) → 'T [] →' T [] Hoán vị các phần tử của mảng theo hoán vị đã chỉ định.
pick: ('T →' U option) → 'T [] →' U Áp dụng hàm đã cung cấp cho các phần tử liên tiếp của một mảng được cung cấp, trả về kết quả đầu tiên trong đó hàm trả về Some (x) cho một số x. Nếu hàm không bao giờ trả về Some (x), thì KeyNotFoundException được nâng lên.
giảm: ('T →' T → 'T) →' T [] → 'T Áp dụng một hàm cho mỗi phần tử của một mảng, xâu chuỗi một đối số tích lũy thông qua tính toán. Nếu hàm đầu vào là f và các phần tử của mảng là i0 ... iN, hàm này tính f (... (f i0 i1) ...) iN. Nếu mảng có kích thước bằng không, ArgumentException được nâng lên.
ReduceBack: ('T →' T → 'T) →' T [] → 'T Áp dụng một hàm cho mỗi phần tử của một mảng, xâu chuỗi một đối số tích lũy thông qua tính toán. Nếu hàm đầu vào là f và các phần tử là i0 ... iN, hàm này tính f i0 (... (f iN-1 iN)). Nếu mảng có kích thước bằng không, ArgumentException được nâng lên.
rev: 'T [] →' T [] Đảo ngược thứ tự của các phần tử trong một mảng được cung cấp.
quét: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → 'T [] →' Trạng thái []) Các hành vi giống như gấp, nhưng trả về kết quả trung gian cùng với kết quả cuối cùng.
scanBack: ('T →' Trạng thái → 'Trạng thái) →' T [] → 'Trạng thái →' Trạng thái [] Hoạt động giống như foldBack, nhưng trả về kết quả trung gian cùng với kết quả cuối cùng.
đặt: 'T [] → int →' T → đơn vị Đặt một phần tử của một mảng.
sắp xếp: 'T [] →' T [] Sắp xếp các phần tử của một mảng và trả về một mảng mới. Operator.compare được sử dụng để so sánh các phần tử.
sortBy: ('T →' Key) → 'T [] →' T [] Sắp xếp các phần tử của một mảng bằng cách sử dụng hàm được cung cấp để biến đổi các phần tử thành kiểu dựa trên thao tác sắp xếp và trả về một mảng mới. Operator.compare được sử dụng để so sánh các phần tử.
sortInPlace: 'T [] → đơn vị Sắp xếp các phần tử của một mảng bằng cách thay đổi mảng tại chỗ, sử dụng hàm so sánh được cung cấp. Operator.compare được sử dụng để so sánh các phần tử.
sortInPlaceBy: ('T →' Key) → 'T [] → đơn vị Sắp xếp các phần tử của một mảng bằng cách thay đổi mảng tại chỗ, sử dụng phép chiếu được cung cấp cho các phím. Operator.compare được sử dụng để so sánh các phần tử.
sortInPlaceWith: ('T →' T → int) → 'T [] → đơn vị Sắp xếp các phần tử của một mảng bằng cách sử dụng hàm so sánh được cung cấp để thay đổi mảng tại chỗ.
sortVới: ('T →' T → int) → 'T [] →' T [] Sắp xếp các phần tử của một mảng bằng cách sử dụng hàm so sánh được cung cấp và trả về một mảng mới.
sub: 'T [] → int → int →' T [] Tạo một mảng có chứa dải con được cung cấp, được chỉ định bằng chỉ số và độ dài bắt đầu.
tổng: 'T [] → ^ T Trả về tổng các phần tử trong mảng.
sumBy: ('T → ^ U) →' T [] → ^ U Trả về tổng kết quả được tạo bằng cách áp dụng một hàm cho từng phần tử của mảng.
toList: 'T [] →' T list Chuyển đổi mảng được cung cấp thành danh sách.
toSeq: 'T [] → seq <' T> Xem mảng được cung cấp dưới dạng một chuỗi.
tryFind: ('T → bool) →' T [] → 'T tùy chọn Trả về phần tử đầu tiên trong mảng được cung cấp mà hàm đã cung cấp trả về true. Lợi nhuậnNone nếu không có phần tử như vậy tồn tại.
tryFindIndex: ('T → bool) →' T [] → int option Trả về chỉ số của phần tử đầu tiên trong mảng thỏa mãn điều kiện đã cung cấp.
tryPick: ('T →' U option) → 'T [] →' U option Áp dụng hàm đã cung cấp cho các phần tử kế tiếp của mảng được cung cấp và trả về kết quả đầu tiên trong đó hàm trả về Some (x) cho một số x. Nếu hàm không bao giờ trả về Some (x),None Được trả lại.
giải nén: ('T1 *' T2) [] → 'T1 [] *' T2 [] Tách một mảng các cặp tuple thành một bộ gồm hai mảng.
giải nén3: ('T1 *' T2 * 'T3) [] →' T1 [] * 'T2 [] *' T3 [] Tách một mảng gồm ba phần tử thành một bộ ba mảng.
zeroCreate: int → 'T [] Tạo một mảng có các phần tử ban đầu được đặt thành giá trị mặc định Unchecked.defaultof <'T>.
zip: 'T1 [] →' T2 [] → ('T1 *' T2) [] Kết hợp hai mảng thành một mảng bộ giá trị có hai phần tử. Hai mảng phải có độ dài bằng nhau; nếu không, ArgumentException được nâng lên.
zip3: 'T1 [] →' T2 [] → 'T3 [] → (' T1 * 'T2 * 113' T3) [] Kết hợp ba mảng thành một mảng bộ giá trị có ba phần tử. Ba mảng phải có độ dài bằng nhau; nếu không, ArgumentException được nâng lên.

Trong phần sau, chúng ta sẽ xem cách sử dụng của một số chức năng này.

Tạo mảng bằng các hàm

Mô-đun Array cung cấp một số chức năng tạo một mảng từ đầu.

  • Các Array.empty hàm tạo một mảng trống mới.

  • Các Array.create hàm tạo một mảng có kích thước xác định và đặt tất cả các phần tử thành các giá trị đã cho.

  • Các Array.init hàm tạo một mảng, cho trước một thứ nguyên và một hàm tạo các phần tử.

  • Các Array.zeroCreate hàm tạo một mảng trong đó tất cả các phần tử được khởi tạo bằng giá trị 0.

  • Các Array.copy hàm tạo một mảng mới chứa các phần tử được sao chép từ một mảng hiện có.

  • Các Array.sub hàm tạo một mảng mới từ một dải con của một mảng.

  • Các Array.append hàm tạo một mảng mới bằng cách kết hợp hai mảng hiện có.

  • Các Array.choose hàm chọn các phần tử của một mảng để đưa vào một mảng mới.

  • Các Array.collect hàm chạy một hàm được chỉ định trên mỗi phần tử mảng của một mảng hiện có và sau đó thu thập các phần tử được tạo bởi hàm và kết hợp chúng thành một mảng mới.

  • Các Array.concat hàm nhận một chuỗi các mảng và kết hợp chúng thành một mảng duy nhất.

  • Các Array.filter hàm nhận một hàm điều kiện Boolean và tạo ra một mảng mới chỉ chứa các phần tử đó từ mảng đầu vào mà điều kiện là đúng.

  • Các Array.rev hàm tạo một mảng mới bằng cách đảo ngược thứ tự của một mảng hiện có.

Các ví dụ sau đây chứng minh các chức năng này:

ví dụ 1

(* using create and set *)
let array1 = Array.create 10 ""
for i in 0 .. array1.Length - 1 do
   Array.set array1 i (i.ToString())
for i in 0 .. array1.Length - 1 do
   printf "%s " (Array.get array1 i)
printfn " "

(* empty array *)
let array2 = Array.empty
printfn "Length of empty array: %d" array2.Length

let array3 = Array.create 10 7.0
printfn "Float Array: %A" array3

(* using the init and zeroCreate *)
let array4 = Array.init 10 (fun index -> index * index)
printfn "Array of squares: %A" array4

let array5 : float array = Array.zeroCreate 10
let (myZeroArray : float array) = Array.zeroCreate 10
printfn "Float Array: %A" array5

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

0 1 2 3 4 5 6 7 8 9
Length of empty array: 0
Float Array: [|7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0; 7.0|]
Array of squares: [|0; 1; 4; 9; 16; 25; 36; 49; 64; 81|]
Float Array: [|0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0; 0.0|]

Ví dụ 2

(* creating subarray from element 5 *)
(* containing 15 elements thereon *)

let array1 = [| 0 .. 50 |]
let array2 = Array.sub array1 5 15
printfn "Sub Array:"
printfn "%A" array2

(* appending two arrays *)
let array3 = [| 1; 2; 3; 4|]
let array4 = [| 5 .. 9 |]
printfn "Appended Array:"
let array5 = Array.append array3 array4
printfn "%A" array5

(* using the Choose function *)
let array6 = [| 1 .. 20 |]
let array7 = Array.choose (fun elem -> if elem % 3 = 0 then
   Some(float (elem))
      else
   None) array6

printfn "Array with Chosen elements:"
printfn "%A" array7

(*using the Collect function *)
let array8 = [| 2 .. 5 |]
let array9 = Array.collect (fun elem -> [| 0 .. elem - 1 |]) array8
printfn "Array with collected elements:"
printfn "%A" array9

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

Sub Array:
[|5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15; 16; 17; 18; 19|]
Appended Array:
[|1; 2; 3; 4; 5; 6; 7; 8; 9|]
Array with Chosen elements:
[|3.0; 6.0; 9.0; 12.0; 15.0; 18.0|]
Array with collected elements:
[|0; 1; 0; 1; 2; 0; 1; 2; 3; 0; 1; 2; 3; 4|]

Tìm kiếm Mảng

Các Array.find hàm nhận một hàm Boolean và trả về phần tử đầu tiên mà hàm trả về true, hàm khác trả về một KeyNotFoundException.

Các Array.findIndex hàm hoạt động tương tự ngoại trừ việc nó trả về chỉ mục của phần tử thay vì chính phần tử đó.

Ví dụ sau đây chứng minh điều này.

Microsoft cung cấp ví dụ chương trình thú vị này, tìm phần tử đầu tiên trong phạm vi của một số nhất định vừa là một hình vuông hoàn hảo vừa là một hình lập phương hoàn hảo -

let array1 = [| 2 .. 100 |]
let delta = 1.0e-10
let 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) array1

let index = Array.findIndex (fun elem -> isPerfectSquare elem && isPerfectCube elem) array1

printfn "The first element that is both a square and a cube is %d and its index is %d." element index

Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:

The first element that is both a square and a cube is 64 and its index is 62.