В F # список — это упорядоченная, неизменная серия элементов одного типа. Это в какой-то степени эквивалентно структуре данных связанного списка.
Модуль F #, Microsoft.FSharp.Collections.List, имеет общие операции со списками. Однако F # импортирует этот модуль автоматически и делает его доступным для каждого приложения F #.
Создание и инициализация списка
Ниже приведены различные способы создания списков.
-
Использование списка литералов .
-
Использование оператора cons (: :).
-
Использование метода List.init модуля List.
-
Использование некоторых синтаксических конструкций, называемых списками .
Использование списка литералов .
Использование оператора cons (: :).
Использование метода List.init модуля List.
Использование некоторых синтаксических конструкций, называемых списками .
Список литералов
В этом методе вы просто указываете разделенную точкой с запятой последовательность значений в квадратных скобках. Например —
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Минусы (: 🙂 Оператор
С помощью этого метода вы можете добавить некоторые значения, добавив или добавив их в существующий список с помощью оператора ::. Например —
let list2 = 1::2::3::4::5::6::7::8::9::10::[];;
[] обозначает пустой список.
Метод инициализации списка
Метод List.init модуля List часто используется для создания списков. Этот метод имеет тип —
val init : int -> (int -> 'T) -> 'T list
Первый аргумент — это желаемая длина нового списка, а второй аргумент — функция инициализатора, которая генерирует элементы в списке.
Например,
let list5 = List.init 5 (fun index -> (index, index * index, index * index * index))
Здесь индексная функция генерирует список.
Список Пониманий
Постижения списков — это специальные синтаксические конструкции, используемые для генерации списков.
Синтаксис понимания списка F # представлен в двух формах — диапазонах и генераторах.
Диапазоны имеют конструкции — [начало .. конец] и [начало .. шаг .. конец]
Например,
let list3 = [1 .. 10]
Генераторы имеют конструкцию — [для x в коллекции do … yield expr]
Например,
let list6 = [ for a in 1 .. 10 do yield (a * a) ]
Когда ключевое слово yield помещает одно значение в список, ключевое слово yield !, помещает коллекцию значений в список.
Следующая функция демонстрирует вышеуказанные методы —
пример
(* 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
Когда вы компилируете и запускаете программу, она выдает следующий вывод:
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]
Свойства типа данных списка
В следующей таблице показаны различные свойства типа данных списка —
Имущество | Тип | Описание |
---|---|---|
Голова | «T | Первый элемент |
пустой | ‘T список | Статическое свойство, которое возвращает пустой список соответствующего типа. |
Пустой | BOOL | Значение true, если в списке нет элементов. |
Вещь | «T | Элемент по указанному индексу (начиная с нуля). |
длина | ИНТ | Количество элементов. |
Хвост | ‘T список | Список без первого элемента. |
В следующем примере показано использование этих свойств —
пример
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))
Когда вы компилируете и запускаете программу, она выдает следующий вывод:
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
Основные операторы в списке
В следующей таблице приведены основные операции с типом данных списка —
Значение | Описание |
---|---|
добавить: ‘T список →’ T список → ‘T список | Возвращает новый список, который содержит элементы первого списка, за которыми следуют элементы второго. |
средний: ‘T список → ^ T | Возвращает среднее значение элементов в списке. |
AverageBy: (‘T → ^ U) →’ T список → ^ U | Возвращает среднее значение элементов, созданных путем применения функции к каждому элементу списка. |
выберите: (опция ‘T →’ U) → ‘T list →’ U list | Применяет данную функцию к каждому элементу списка. Возвращает список, состоящий из результатов для каждого элемента, где функция возвращает Some . |
собрать: (‘T →’ U list) → ‘T list →’ U list | Для каждого элемента списка применяется данная функция. Объединяет все результаты и возвращает объединенный список. |
concat: seq <‘T list> →’ T list | Возвращает новый список, который содержит элементы каждого списка в порядке. |
пусто: ‘T список | Возвращает пустой список данного типа. |
существует: (‘T → bool) →’ T список → bool | Проверяет, удовлетворяет ли какой-либо элемент списка данному предикату. |
Существует2: (‘T1 →’ T2 → bool) → ‘Список T1 →’ Список T2 → bool | Проверяет, удовлетворяет ли любая пара соответствующих элементов списков данному предикату. |
фильтр: (‘T → bool) →’ T list → ‘T list | Возвращает новую коллекцию, содержащую только те элементы коллекции, для которых данный предикат возвращает true . |
найти: (‘T → bool) →’ T list → ‘T | Возвращает первый элемент, для которого данная функция возвращает true . |
findIndex: (‘T → bool) →’ T list → int | Возвращает индекс первого элемента в списке, который удовлетворяет данному предикату. |
свернуть: (‘State →’ T → ‘State) →’ State → ‘T list →’ State | Применяет функцию к каждому элементу коллекции, пропуская аргумент аккумулятора через вычисления. Эта функция принимает второй аргумент и применяет к нему функцию и первый элемент списка. Затем он передает этот результат в функцию вместе со вторым элементом и так далее. Наконец, он возвращает окончательный результат. Если входной функцией является f, а элементами i0 … iN, то эта функция вычисляет f (… (fs i0) i1 …) iN. |
fold2: (‘State →’ T1 → ‘T2 →’ State) → ‘State →’ T1 list → ‘T2 list →’ State | Применяет функцию к соответствующим элементам двух коллекций, пропуская аргумент аккумулятора через вычисления. Коллекции должны иметь одинаковые размеры. Если входной функцией является f, а элементами являются i0 … iN и j0 … jN, то эта функция вычисляет f (… (fs i0 j0) …) iN jN. |
foldBack: (‘T →’ State → ‘State) →’ T list → ‘State →’ State | Применяет функцию к каждому элементу коллекции, пропуская аргумент аккумулятора через вычисления. Если входная функция isf и элементы i0 … iN, то вычисляется f i0 (… (f iN s)). |
foldBack2: (‘T1 →’ T2 → ‘State →’ State) → ‘T1 list →’ T2 list → ‘State →’ State | Применяет функцию к соответствующим элементам двух коллекций, пропуская аргумент аккумулятора через вычисления. Коллекции должны иметь одинаковые размеры. Если входной функцией является f, а элементами являются i0 … iN и j0 … jN, то эта функция вычисляет f i0 j0 (… (f iN jN s)). |
forall: (‘T → bool) →’ T list → bool | Проверяет, все ли элементы коллекции удовлетворяют данному предикату. |
forall2: (‘T1 →’ T2 → bool) → ‘Список T1 →’ Список T2 → bool | Проверяет, все ли соответствующие элементы коллекции удовлетворяют заданному предикату попарно. |
руководитель: ‘T список →’ T | Возвращает первый элемент списка. |
init: int → (int → ‘T) →’ T list | Создает список, вызывая данный генератор для каждого индекса. |
isEmpty: ‘T list → bool | Возвращает true, если список не содержит элементов, иначе false . |
iter: (‘T → единица измерения) →’ T список → единица измерения | Применяет данную функцию к каждому элементу коллекции. |
iter2: (‘T1 →’ T2 → единица) → ‘Список T1 →’ Список T2 → единица | Применяет данную функцию одновременно к двум коллекциям. Коллекции должны иметь одинаковый размер. |
iteri: (int → ‘T → unit) →’ T list → unit | Применяет данную функцию к каждому элементу коллекции. Целое число, переданное функции, указывает на индекс элемента. |
iteri2: (int → ‘T1 →’ T2 → unit) → ‘T1 list →’ T2 list → unit | Применяет данную функцию одновременно к двум коллекциям. Коллекции должны иметь одинаковый размер. Целое число, переданное функции, указывает на индекс элемента. |
длина: ‘T список → int | Возвращает длину списка. |
карта: (‘T →’ U) → ‘T list →’ U list | Создает новую коллекцию, элементы которой являются результатами применения данной функции к каждому из элементов коллекции. |
map2: (‘T1 →’ T2 → ‘U) →’ список T1 → ‘список T2 →’ список U | Создает новую коллекцию, элементы которой являются результатами применения данной функции к соответствующим элементам двух коллекций попарно. |
map3: (‘T1 →’ T2 → ‘T3 →’ U) → ‘список T1 →’ список T2 → ‘список T3 →’ список U | Создает новую коллекцию, элементы которой являются результатом применения данной функции к соответствующим элементам трех коллекций одновременно. |
mapi: (int → ‘T →’ U) → ‘T list →’ U list | Создает новую коллекцию, элементы которой являются результатами применения данной функции к каждому из элементов коллекции. Целочисленный индекс, переданный функции, указывает индекс (от 0) преобразовываемого элемента. |
mapi2: (int → ‘T1 →’ T2 → ‘U) →’ список T1 → ‘список T2 →’ список U | Как и List.mapi, но отображает соответствующие элементы из двух списков одинаковой длины. |
max: ‘T list →’ T | Возвращает наибольший из всех элементов списка по сравнению с использованием Operators.max. |
maxBy: (‘T →’ U) → ‘T list →’ T | Возвращает наибольший из всех элементов списка по сравнению с использованием Operators.max для результата функции. |
мин: ‘T список →’ T | Возвращает самый низкий из всех элементов списка по сравнению с использованием Operators.min. |
minBy: (‘T →’ U) → ‘T list →’ T | Возвращает самый низкий из всех элементов списка по сравнению с использованием Operators.min для результата функции |
nth: ‘T list → int →’ T | Индексы в список. Первый элемент имеет индекс 0. |
ofArray: ‘T [] →’ T list | Создает список из заданного массива. |
ofSeq: seq <‘T> →’ T list | Создает новый список из данного перечисляемого объекта. |
раздел: (‘T → bool) →’ T list * ‘T list | Разбивает коллекцию на две коллекции, содержащие элементы, для которых данный предикат возвращает true и false соответственно. |
перестановка: (int → int) → ‘T list →’ T list | Возвращает список со всеми переставленными элементами в соответствии с указанной перестановкой. |
выберите: (опция ‘T →’ U) → ‘список T →’ U | Применяет данную функцию к последовательным элементам, возвращая первый результат, где функция возвращает Some для некоторого значения. |
уменьшить: (‘T →’ T → ‘T) →’ T list → ‘T | Применяет функцию к каждому элементу коллекции, пропуская аргумент аккумулятора через вычисления. Эта функция применяет указанную функцию к первым двум элементам списка. Затем он передает этот результат в функцию вместе с третьим элементом и так далее. Наконец, он возвращает окончательный результат. Если входной функцией является f, а элементами — i0 … iN, то эта функция вычисляет f (… (f i0 i1) i2 …) iN. |
ReduckBack: (‘T →’ T → ‘T) →’ T list → ‘T | Применяет функцию к каждому элементу коллекции, пропуская аргумент аккумулятора через вычисления. Если входная функция isf и элементы i0 … iN, то эта функция вычисляет f i0 (… (f iN-1 iN)). |
копия: (int → ‘T →’ T список) | Создает список, вызывая данный генератор для каждого индекса. |
rev: ‘T list →’ T list | Возвращает новый список с элементами в обратном порядке. |
scan: (‘State →’ T → ‘State) →’ State → ‘T list →’ Список состояний | Применяет функцию к каждому элементу коллекции, пропуская аргумент аккумулятора через вычисления. Эта функция принимает второй аргумент и применяет к нему указанную функцию и первый элемент списка. Затем он передает этот результат в функцию вместе со вторым элементом и так далее. Наконец, он возвращает список промежуточных результатов и окончательный результат. |
scanBack: (‘T →’ State → ‘State) →’ T list → ‘State →’ Список состояний | Как и foldBack, но возвращает промежуточные и окончательные результаты |
сортировка: ‘T list →’ T list | Сортирует указанный список с помощью Operators.compare. |
sortBy: (‘T →’ Key) → ‘T list →’ T list | Сортирует данный список, используя ключи, заданные данной проекцией. Ключи сравниваются с помощью Operators.compare. |
sortWith: (‘T →’ T → int) → ‘T list →’ T list | Сортирует указанный список, используя данную функцию сравнения. |
сумма: ^ T список → ^ T | Возвращает сумму элементов в списке. |
sumBy: (‘T → ^ U) →’ T список → ^ U | Возвращает сумму результатов, полученных с помощью применения функции к каждому элементу списка. |
хвост: ‘T список →’ T список | Возвращает список ввода без первого элемента. |
toArray: ‘T list →’ T [] | Создает массив из заданного списка. |
toSeq: ‘T list → seq <‘ T> | Рассматривает данный список как последовательность. |
tryFind: (‘T → bool) →’ T list → ‘T опция | Возвращает первый элемент, для которого данная функция возвращает true . Вернуть None, если такого элемента не существует. |
tryFindIndex: (‘T → bool) →’ T list → int option | Возвращает индекс первого элемента в списке, который удовлетворяет данному предикату. Вернуть None, если такого элемента не существует. |
tryPick: (опция ‘T →’ U) → опция ‘T list →’ U | Применяет данную функцию к последовательным элементам, возвращая первый результат, где функция возвращает Some для некоторого значения. Если такого элемента не существует, вернуть None . |
распаковать: (‘T1 *’ T2) список → ‘T1 список *’ список T2 | Разбивает список пар на два списка. |
распаковать3: (‘T1 *’ T2 * ‘T3) список →’ список T1 * ‘список T2 *’ список T3 | Разбивает список троек на три списка. |
zip: ‘T1 list →’ T2 list → (‘T1 *’ T2) список | Объединяет два списка в список пар. Два списка должны иметь одинаковую длину. |
zip3: ‘T1 list →’ T2 list → ‘T3 list → (‘ T1 * ‘T2 *’ T3) список | Объединяет три списка в список троек. Списки должны иметь одинаковую длину. |
Следующие примеры демонстрируют использование вышеуказанных функций —
Пример 1
Эта программа показывает рекурсивное изменение списка —
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)
Когда вы компилируете и запускаете программу, она выдает следующий вывод:
The original list: [2; 4; 6; 8; 10; 12; 14; 16] The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
Тем не менее, вы можете использовать функцию rev модуля для той же цели —
let list1 = [ 2; 4; 6; 8; 10; 12; 14; 16 ] printfn "The original list: %A" list1 printfn "The reversed list: %A" (List.rev list1)
Когда вы компилируете и запускаете программу, она выдает следующий вывод:
The original list: [2; 4; 6; 8; 10; 12; 14; 16] The reversed list: [16; 14; 12; 10; 8; 6; 4; 2]
Пример 2
Эта программа показывает фильтрацию списка с использованием метода List.filter —
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
Когда вы компилируете и запускаете программу, она выдает следующий вывод:
The list: [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] The Filtered list: [2; 4; 6; 8; 10]
Пример 3
Метод List.map отображает список из одного типа в другой —
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
Когда вы компилируете и запускаете программу, она выдает следующий вывод:
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"]
Пример 4
Метод List.append и оператор @ добавляет один список в другой —
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
Когда вы компилируете и запускаете программу, она выдает следующий вывод:
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']
Пример 5
Метод List.sort сортирует список. Метод List.sum дает сумму элементов в списке, а метод List.average — среднее значение элементов в списке.
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
Когда вы компилируете и запускаете программу, она выдает следующий вывод:
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
Операция «сгиба» применяет функцию к каждому элементу в списке, агрегирует результат функции в переменной аккумулятора и возвращает аккумулятор как результат операции сгиба.
Пример 6
Метод List.fold применяет функцию к каждому элементу слева направо, в то время как List.foldBack применяет функцию к каждому элементу справа налево.
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 ])
Когда вы компилируете и запускаете программу, она выдает следующий вывод: