F # - Danh sách
Trong F #, một danh sách là một chuỗi các phần tử cùng kiểu có thứ tự, bất biến. Ở một mức độ nào đó, nó tương đương với cấu trúc dữ liệu danh sách liên kết.
Mô-đun F #, Microsoft.FSharp.Collections.List,có các hoạt động phổ biến trên danh sách. Tuy nhiên, F # tự động nhập mô-đun này và làm cho nó có thể truy cập được cho mọi ứng dụng F #.
Tạo và khởi tạo danh sách
Sau đây là các cách tạo danh sách khác nhau -
Sử dụng danh sách literals.
Sử dụng cons (::) nhà điều hành.
Sử dụng List.init phương thức của mô-đun Danh sách.
Sử dụng một số syntactic constructs gọi là List Comprehensions.
Liệt kê các chữ
Trong phương pháp này, bạn chỉ cần chỉ định một chuỗi giá trị được phân tách bằng dấu chấm phẩy trong dấu ngoặc vuông. Ví dụ -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Khuyết điểm (: :) Toán tử
Với phương pháp này, bạn có thể thêm một số giá trị bằng cách thêm trước hoặc cons-ingnó vào danh sách hiện có bằng cách sử dụng toán tử ::. Ví dụ -
let list2 = 1::2::3::4::5::6::7::8::9::10::[];;
[] biểu thị một danh sách trống.
Liệt kê phương pháp init
Phương thức List.init của mô-đun Danh sách thường được sử dụng để tạo danh sách. Phương thức này có kiểu -
val init : int -> (int -> 'T) -> 'T list
Đối số đầu tiên là độ dài mong muốn của danh sách mới và đối số thứ hai là một hàm khởi tạo, hàm này tạo các mục trong danh sách.
Ví dụ,
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
Tại đây, hàm chỉ mục tạo danh sách.
Liệt kê toàn bộ
Danh sách hiểu là cấu trúc cú pháp đặc biệt được sử dụng để tạo danh sách.
Cú pháp hiểu danh sách F # có hai dạng - phạm vi và trình tạo.
Dải ô có các cấu trúc - [bắt đầu .. kết thúc] và [bắt đầu .. bước .. kết thúc]
Ví dụ,
let list3 = [1 .. 10]
Trình tạo có cấu trúc - [cho x trong bộ sưu tập do ... sản lượng expr]
Ví dụ,
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
Như yield từ khóa đẩy một giá trị vào danh sách, từ khóa, yield!, đẩy một tập hợp các giá trị vào danh sách.
Hàm sau thể hiện các phương pháp trên:
Thí dụ
(* using list literals *)
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
(*using cons operator *)
let list2 = 1 :: 2 :: 3 :: []
printfn "The list: %A" list2
(* using range constructs*)
let list3 = [1 .. 10]
printfn "The list: %A" list3
(* using range constructs *)
let list4 = ['a' .. 'm']
printfn "The list: %A" list4
(* using init method *)
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
printfn "The list: %A" list5
(* using yield operator *)
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
printfn "The list: %A" list6
(* using yield operator *)
let list7 = [ for a in 1 .. 100 do if a % 3 = 0 && a % 5 = 0 then yield a]
printfn "The list: %A" list7
(* using yield! operator *)
let list8 = [for a in 1 .. 3 do yield! [ a .. a + 3 ] ]
printfn "The list: %A" list8
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 list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: [1; 2; 3]
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The list: ['a'; 'b'; 'c'; 'd'; 'e'; 'f'; 'g'; 'h'; 'i'; 'j'; 'k'; 'l'; 'm']
The list: [(0, 0, 0); (1, 1, 1); (2, 4, 8); (3, 9, 27); (4, 16, 64)]
The list: [1; 4; 9; 16; 25; 36; 49; 64; 81; 100]
The list: [15; 30; 45; 60; 75; 90]
The list: [1; 2; 3; 4; 2; 3; 4; 5; 3; 4; 5; 6]
Thuộc tính của kiểu dữ liệu danh sách
Bảng sau đây cho thấy các thuộc tính khác nhau của kiểu dữ liệu danh sách:
Bất động sản | Kiểu | Sự miêu tả |
---|---|---|
Cái đầu | 'T | Yếu tố đầu tiên. |
Trống | 'T danh sách | Thuộc tính tĩnh trả về một danh sách trống có kiểu thích hợp. |
IsEmpty | bool | true nếu danh sách không có phần tử. |
Mục | 'T | Phần tử tại chỉ mục được chỉ định (dựa trên không). |
Chiều dài | int | Số lượng phần tử. |
Đuôi | 'T danh sách | Danh sách không có phần tử đầu tiên. |
Ví dụ sau cho thấy việc sử dụng các thuộc tính này:
Thí dụ
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
// Use of Properties
printfn "list1.IsEmpty is %b" (list1.IsEmpty)
printfn "list1.Length is %d" (list1.Length)
printfn "list1.Head is %d" (list1.Head)
printfn "list1.Tail.Head is %d" (list1.Tail.Head)
printfn "list1.Tail.Tail.Head is %d" (list1.Tail.Tail.Head)
printfn "list1.Item(1) is %d" (list1.Item(1))
Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:
list1.IsEmpty is false
list1.Length is 8
list1.Head is 2
list1.Tail.Head is 4
list1.Tail.Tail.Head is 6
list1.Item(1) is 4
Các toán tử cơ bản trong danh sách
Bảng sau đây trình bày các thao tác cơ bản trên kiểu dữ liệu danh sách:
Giá trị | Sự miêu tả |
---|---|
nối thêm: 'Danh sách T →' Danh sách T → 'Danh sách T | Trả về một danh sách mới chứa các phần tử của danh sách đầu tiên theo sau là các phần tử của danh sách thứ hai. |
trung bình: 'T danh sách → ^ T | Trả về giá trị trung bình của các phần tử trong danh sách. |
AverageBy: ('T → ^ U) →' Danh sách 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 hàm cho mỗi phần tử của danh sách. |
chọn: ('T →' U option) → 'T list →' U list | Áp dụng chức năng đã cho cho từng phần tử của danh sách. Trả về danh sách bao gồm các kết quả cho từng phần tử mà hàm trả vềSome. |
thu thập: ('T →' Danh sách U) → 'Danh sách T →' Danh sách U | Đối với mỗi phần tử của danh sách, hãy áp dụng chức năng đã cho. Nối tất cả các kết quả và trả về danh sách kết hợp. |
concat: seq <'T list> →' T list | Trả về một danh sách mới chứa các phần tử của từng danh sách theo thứ tự. |
rỗng: 'T danh sách | Trả về danh sách trống của kiểu đã cho. |
tồn tại: ('T → bool) →' Danh sách T → bool | Kiểm tra xem có phần tử nào của danh sách thỏa mãn vị từ đã cho hay không. |
tồn tại2: ('T1 →' T2 → bool) → 'Danh sách T1 →' Danh sách T2 → bool | Kiểm tra xem có cặp phần tử tương ứng nào của danh sách thỏa mãn vị từ đã cho hay không. |
bộ lọc: ('T → bool) →' Danh sách T → 'Danh sách T | Trả về một tập hợp mới chỉ chứa các phần tử của tập hợp mà vị từ đã cho trả về true. |
find: ('T → bool) →' T list → 'T | Trả về phần tử đầu tiên mà hàm đã cho trả về true. |
findIndex: ('T → bool) →' T list → int | Trả về chỉ số của phần tử đầu tiên trong danh sách thỏa mãn vị từ đã cho. |
gấp: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → 'Danh sách T →' Trạng thái | Áp dụng một hàm cho từng phần tử của tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Hàm này nhận đối số thứ hai và áp dụng hàm cho nó và phần tử đầu tiên của danh sách. Sau đó, nó chuyển kết quả này vào hàm cùng với phần tử thứ hai, v.v. Cuối cùng, nó trả về kết quả cuối cùng. Nếu hàm đầu vào là f và các phần tử là i0 ... iN, thì hàm này tính f (... (fs i0) i1 ...) iN. |
fold2: ('Trạng thái →' T1 → 'T2 →' Trạng thái) → 'Trạng thái →' Danh sách T1 → 'Danh sách T2 →' Trạng thái | Áp dụng một hàm cho các phần tử tương ứng của hai tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Các bộ sưu tập phải có kích thước giống hệt nhau. Nếu hàm đầu vào là f và các phần tử là i0 ... iN và j0 ... jN, thì hàm này tính f (... (fs i0 j0) ...) iN jN. |
foldBack: ('T →' Trạng thái → 'Trạng thái) →' Danh sách T → 'Trạng thái →' Trạng thái | Áp dụng một hàm cho từng phần tử của tập hợp, 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 thì tính f i0 (... (f iN s)). |
foldBack2: ('T1 →' T2 → 'Trạng thái →' Trạng thái) → 'Danh sách T1 →' Danh sách T2 → 'Trạng thái →' Trạng thái | Áp dụng một hàm cho các phần tử tương ứng của hai tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Các bộ sưu tập phải có kích thước giống hệt nhau. Nếu hàm đầu vào là f và các phần tử là i0 ... iN và j0 ... jN, thì hàm này tính f i0 j0 (... (f iN jN s)). |
forall: ('T → bool) →' T list → bool | Kiểm tra xem tất cả các phần tử của tập hợp có thỏa mãn vị từ đã cho hay không. |
forall2: ('T1 →' T2 → bool) → 'Danh sách T1 →' Danh sách T2 → bool | Kiểm tra xem tất cả các phần tử tương ứng của tập hợp có thỏa mãn từng cặp vị từ đã cho hay không. |
head: 'T list →' T | Trả về phần tử đầu tiên của danh sách. |
init: int → (int → 'T) →' T danh sách | Tạo danh sách bằng cách gọi trình tạo đã cho trên mỗi chỉ mục. |
isEmpty: 'T list → bool | Lợi nhuận true nếu danh sách không chứa phần tử, false nếu không thì. |
iter: ('T → đơn vị) →' T danh sách → đơn vị | Áp dụng chức năng đã cho cho từng phần tử của tập hợp. |
iter2: ('T1 →' T2 → đơn vị) → 'Danh sách T1 →' Danh sách T2 → đơn vị | Áp dụng chức năng đã cho cho hai tập hợp đồng thời. Các bộ sưu tập phải có kích thước giống hệt nhau. |
iteri: (int → 'T → đơn vị) →' Danh sách T → đơn vị | Áp dụng chức năng đã cho cho từng phần tử của tập hợp. 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ị) → 'Danh sách T1 →' Danh sách T2 → đơn vị | Áp dụng hàm đã cho cho hai bộ sưu tập đồng thời. Các bộ sưu tập phải có kích thước giống hệt nhau. Số nguyên được truyền vào hàm cho biết chỉ số của phần tử. |
length: 'T list → int | Trả về độ dài của danh sách. |
map: ('T →' U) → 'Danh sách T →' Danh sách U | Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho từng phần tử của tập hợp. |
map2: ('T1 →' T2 → 'U) →' Danh sách T1 → 'Danh sách T2 →' Danh sách U | Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho các phần tử tương ứng của hai tập hợp theo cặp. |
map3: ('T1 →' T2 → 'T3 →' U) → 'Danh sách T1 →' Danh sách T2 → 'Danh sách T3 →' Danh sách U | Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho các phần tử tương ứng của ba tập hợp đồng thời. |
mapi: (int → 'T →' U) → 'T list →' U list | Tạo một tập hợp mới có các phần tử là kết quả của việc áp dụng hàm đã cho cho từng phần tử của tập hợp. Chỉ số số nguyên được chuyển đến hàm cho biết chỉ số (từ 0) của phần tử được chuyển đổi. |
mapi2: (int → 'T1 →' T2 → 'U) →' Danh sách T1 → 'Danh sách T2 →' Danh sách U | Giống như List.mapi, nhưng ánh xạ các phần tử tương ứng từ hai danh sách có độ dài bằng nhau. |
tối đa: 'T danh sách →' T | Trả về giá trị lớn nhất trong số tất cả các phần tử của danh sách, được so sánh bằng cách sử dụng Operator.max. |
maxBy: ('T →' U) → 'Danh sách T →' T | Trả về giá trị lớn nhất trong số tất cả các phần tử của danh sách, được so sánh bằng cách sử dụng Operator.max trên kết quả hàm. |
tối thiểu: 'T list →' T | Trả về giá trị thấp nhất trong số tất cả các phần tử của danh sách, được so sánh bằng cách sử dụng Operator.min. |
minBy: ('T →' U) → 'T list →' T | Trả về giá trị thấp nhất trong số tất cả các phần tử của danh sách, được so sánh bằng cách sử dụng Operator.min trên kết quả hàm |
nth: 'T list → int →' T | Chỉ mục vào danh sách. Phần tử đầu tiên có chỉ số 0. |
ofArray: 'T [] →' Danh sách T | Tạo danh sách từ mảng đã cho. |
ofSeq: seq <'T> →' T list | Tạo danh sách mới từ đối tượng liệt kê đã cho. |
phân vùng: ('T → bool) →' Danh sách T * 'Danh sách T | Tách tập hợp thành hai tập hợp, chứa các phần tử mà vị từ đã cho trả về true và false tương ứng. |
hoán vị: (int → int) → 'Danh sách T →' Danh sách T | Trả về một danh sách với tất cả các phần tử được hoán vị theo phép hoán vị đã chỉ định. |
pick: ('T →' U option) → 'T list →' U | Áp dụng hàm đã cho cho các phần tử kế tiếp, trả về kết quả đầu tiên trong đó hàm trả về Some cho một số giá trị. |
giảm: ('T →' T → 'T) →' Danh sách T → 'T | Áp dụng một hàm cho từng phần tử của tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Hàm này áp dụng chức năng được chỉ định cho hai phần tử đầu tiên của danh sách. Sau đó, nó chuyển kết quả này vào hàm cùng với phần tử thứ ba, v.v. Cuối cùng, nó trả về kết quả cuối cùng. Nếu hàm đầu vào là f và các phần tử là i0 ... iN, thì hàm này tính f (... (f i0 i1) i2 ...) iN. |
ReduceBack: ('T →' T → 'T) →' Danh sách T → 'T | Áp dụng một hàm cho từng phần tử của tập hợp, 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, thì hàm này tính f i0 (... (f iN-1 iN)). |
nhân bản: (int → 'T →' T danh sách) | Tạo danh sách bằng cách gọi trình tạo đã cho trên mỗi chỉ mục. |
rev: 'Danh sách T →' Danh sách T | Trả về một danh sách mới với các phần tử theo thứ tự ngược lại. |
quét: ('Trạng thái →' T → 'Trạng thái) →' Trạng thái → 'Danh sách T →' Danh sách trạng thái | Áp dụng một hàm cho từng phần tử của tập hợp, xâu chuỗi một đối số tích lũy thông qua tính toán. Hàm này nhận đối số thứ hai và áp dụng hàm đã chỉ định cho nó và phần tử đầu tiên của danh sách. Sau đó, nó chuyển kết quả này vào hàm cùng với phần tử thứ hai, v.v. Cuối cùng, nó trả về danh sách các kết quả trung gian và kết quả cuối cùng. |
scanBack: ('T →' State → 'State) →' T list → 'State →' State list | Giống như foldBack, nhưng trả về cả kết quả trung gian và kết quả cuối cùng |
sắp xếp: 'Danh sách T →' Danh sách T | Sắp xếp danh sách đã cho bằng Operator.compare. |
sortBy: ('T →' Key) → 'T list →' T. list | Sắp xếp danh sách đã cho bằng các phím được cung cấp bởi phép chiếu đã cho. Các khóa được so sánh bằng Operator.compare. |
sortVới: ('T →' T → int) → 'T list →' T list | Sắp xếp danh sách đã cho bằng chức năng so sánh đã cho. |
sum: ^ T danh sách → ^ T | Trả về tổng các phần tử trong danh sách. |
sumBy: ('T → ^ U) →' T danh sách → ^ U | Trả về tổng kết quả được tạo bằng cách áp dụng hàm cho từng phần tử của danh sách. |
tail: 'Danh sách T →' Danh sách T | Trả về danh sách đầu vào không có phần tử đầu tiên. |
toArray: 'T list →' T [] | Tạo một mảng từ danh sách đã cho. |
toSeq: 'T list → seq <' T> | Xem danh sách đã cho dưới dạng một chuỗi. |
tryFind: ('T → bool) →' Danh sách T → 'Tùy chọn T | Trả về phần tử đầu tiên mà hàm đã cho trả về true. Trở vềNone nếu không có phần tử như vậy tồn tại. |
tryFindIndex: ('T → bool) →' T list → int option | Trả về chỉ số của phần tử đầu tiên trong danh sách thỏa mãn vị từ đã cho. Trở vềNone nếu không có phần tử như vậy tồn tại. |
tryPick: ('T →' U option) → 'T list →' U option | Áp dụng hàm đã cho cho các phần tử kế tiếp, trả về kết quả đầu tiên trong đó hàm trả về Somecho một số giá trị. Nếu không có phần tử như vậy tồn tại thì trả vềNone. |
giải nén: ('T1 *' T2) danh sách → 'Danh sách T1 *' Danh sách T2 | Tách một danh sách các cặp thành hai danh sách. |
giải nén3: ('T1 *' T2 * 'T3) danh sách →' Danh sách T1 * 'Danh sách T2 *' Danh sách T3 | Tách danh sách bộ ba thành ba danh sách. |
zip: 'Danh sách T1 →' Danh sách T2 → ('T1 *' T2) danh sách | Kết hợp hai danh sách thành một danh sách các cặp. Hai danh sách phải có độ dài bằng nhau. |
zip3: 'Danh sách T1 →' Danh sách T2 → 'Danh sách T3 → (' T1 * 'T2 *' T3) danh sách | Kết hợp ba danh sách thành một danh sách bộ ba. Các danh sách phải có độ dài bằng nhau. |
Các ví dụ sau đây chứng minh việc sử dụng các chức năng trên:
ví dụ 1
Chương trình này hiển thị việc đảo ngược một danh sách một cách đệ quy -
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
let reverse lt =
let rec loop acc = function
| [] -> acc
| hd :: tl -> loop (hd :: acc) tl
loop [] lt
printfn "The reversed list: %A" (reverse list1)
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 original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
Tuy nhiên, bạn có thể sử dụng rev chức năng của mô-đun cho cùng mục đích -
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ]
printfn "The original list: %A" list1
printfn "The reversed list: %A" (List.rev list1)
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 original list: [2; 4; 6; 8; 10; 12; 14; 16]
The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
Ví dụ 2
Chương trình này hiển thị lọc một danh sách bằng cách sử dụng List.filter phương pháp -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.filter (fun x -> x % 2 = 0);;
printfn "The Filtered list: %A" list2
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 list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Filtered list: [2; 4; 6; 8; 10]
Ví dụ 3
Các List.map phương pháp ánh xạ danh sách từ loại này sang loại khác -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
printfn "The list: %A" list1
let list2 = list1 |> List.map (fun x -> (x * x).ToString());;
printfn "The Mapped list: %A" list2
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 list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The Mapped list: ["1"; "4"; "9"; "16"; "25"; "36"; "49"; "64"; "81"; "100"]
Ví dụ 4
Các List.append và toán tử @ nối một danh sách với một danh sách khác -
let list1 = [1; 2; 3; 4; 5 ]
let list2 = [6; 7; 8; 9; 10]
let list3 = List.append list1 list2
printfn "The first list: %A" list1
printfn "The second list: %A" list2
printfn "The appened list: %A" list3
let lt1 = ['a'; 'b';'c' ]
let lt2 = ['e'; 'f';'g' ]
let lt3 = lt1 @ lt2
printfn "The first list: %A" lt1
printfn "The second list: %A" lt2
printfn "The appened list: %A" lt3
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 list: [1; 2; 3; 4; 5]
The second list: [6; 7; 8; 9; 10]
The appened list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
The first list: ['a'; 'b'; 'c']
The second list: ['e'; 'f'; 'g']
The appened list: ['a'; 'b'; 'c'; 'e'; 'f'; 'g']
Ví dụ 5
Các List.sortphương pháp sắp xếp một danh sách. CácList.sum phương thức cung cấp tổng các phần tử trong danh sách và List.average phương pháp cho biết giá trị trung bình của các phần tử trong danh sách -
let list1 = [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
printfn "The list: %A" list1
let list2 = List.sort list1
printfn "The sorted list: %A" list2
let s = List.sum list1
let avg = List.average list1
printfn "The sum: %f" s
printfn "The average: %f" avg
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 list: [9.0; 0.0; 2.0; -4.5; 11.2; 8.0; -10.0]
The sorted list: [-10.0; -4.5; 0.0; 2.0; 8.0; 9.0; 11.2]
The sum: 15.700000
The average: 2.242857
Phép toán "gấp" áp dụng một hàm cho từng phần tử trong danh sách, tổng hợp kết quả của hàm trong một biến tích lũy và trả về bộ tích lũy là kết quả của thao tác gấp.
Ví dụ 6
Các List.fold phương thức áp dụng một hàm cho từng phần tử từ trái sang phải, trong khi List.foldBack áp dụng một chức năng cho mỗi phần tử từ phải sang trái.
let sumList list = List.fold (fun acc elem -> acc + elem) 0 list
printfn "Sum of the elements of list %A is %d." [ 1 .. 10 ] (sumList [ 1 .. 10 ])
Khi bạn biên dịch và thực thi chương trình, nó sẽ tạo ra kết quả sau:
Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.