F # - Списки
В F # список - это упорядоченная неизменяемая последовательность элементов одного типа. В некоторой степени это эквивалентно структуре данных связанного списка.
Модуль F #, Microsoft.FSharp.Collections.List,имеет общие операции со списками. Однако F # автоматически импортирует этот модуль и делает его доступным для каждого приложения F #.
Создание и инициализация списка
Ниже приведены различные способы создания списков.
Использование списка literals.
С помощью cons (: :) оператор.
Используя List.init метод модуля List.
Используя некоторые syntactic constructs называется List Comprehensions.
Список литералов
В этом методе вы просто указываете последовательность значений, разделенных точкой с запятой, в квадратных скобках. Например -
let list1 = [1; 2; 3; 4; 5; 6; 7; 8; 9; 10]
Минусы (: :) Оператор
С помощью этого метода вы можете добавить некоторые значения, добавив или cons-ingв существующий список с помощью оператора ::. Например -
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 список | Статическое свойство, возвращающее пустой список соответствующего типа. |
Пусто | bool | true если в списке нет элементов. |
Вещь | 'Т | Элемент по указанному индексу (с нуля). |
Длина | int | Количество элементов. |
Хвост | '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 список →' U список | Применяет данную функцию к каждому элементу списка. Возвращает список, состоящий из результатов для каждого элемента, в котором функция возвращаетSome. |
собрать: ('T →' U список) → 'T список →' U список | Для каждого элемента списка применяет данную функцию. Объединяет все результаты и возвращает объединенный список. |
concat: seq <'T список> →' T список | Возвращает новый список, содержащий по порядку элементы каждого списка. |
пустой: 'T список | Возвращает пустой список заданного типа. |
существует: ('T → bool) →' T list → bool | Проверяет, удовлетворяет ли какой-либо элемент списка заданному предикату. |
существует2: ('T1 →' T2 → bool) → 'T1 список →' T2 список → bool | Проверяет, удовлетворяет ли любая пара соответствующих элементов списков заданному предикату. |
фильтр: ('T → bool) →' T список → 'T список | Возвращает новую коллекцию, содержащую только элементы коллекции, для которой данный предикат возвращает true. |
найти: ('T → bool) →' T список → 'T | Возвращает первый элемент, для которого данная функция возвращает true. |
findIndex: ('T → bool) →' T список → int | Возвращает индекс первого элемента в списке, который удовлетворяет заданному предикату. |
свёртка: ('Состояние →' T → 'Состояние) →' Состояние → 'Список T →' Состояние | Применяет функцию к каждому элементу коллекции, передавая аргумент аккумулятора через вычисление. Эта функция принимает второй аргумент и применяет функцию к нему и первому элементу списка. Затем он передает этот результат в функцию вместе со вторым элементом и так далее. Наконец, он возвращает окончательный результат. Если входная функция - f, а элементы - i0 ... iN, то эта функция вычисляет f (... (fs i0) i1 ...) iN. |
fold2: ('Состояние →' T1 → 'T2 →' Состояние) → 'Состояние →' Список T1 → 'Список T2 →' Состояние | Применяет функцию к соответствующим элементам двух коллекций, передавая аргумент аккумулятора через вычисление. Коллекции должны иметь одинаковые размеры. Если входной функцией является f, а элементами являются i0 ... iN и j0 ... jN, то эта функция вычисляет f (... (fs i0 j0) ...) iN jN. |
foldBack: ('T →' Состояние → 'Состояние) →' T список → 'Состояние →' Состояние | Применяет функцию к каждому элементу коллекции, передавая аргумент аккумулятора через вычисление. Если входная функция равна f, а элементы - i0 ... iN, то вычисляет f i0 (... (f iN s)). |
foldBack2: ('T1 →' T2 → 'State →' State) → 'T1 list →' T2 list → 'State →' Состояние | Применяет функцию к соответствующим элементам двух коллекций, передавая аргумент аккумулятора через вычисление. Коллекции должны иметь одинаковые размеры. Если входной функцией является f, а элементами являются i0 ... iN и j0 ... jN, то эта функция вычисляет f i0 j0 (... (f iN jN s)). |
forall: ('T → bool) →' T список → bool | Проверяет, все ли элементы коллекции удовлетворяют заданному предикату. |
forall2: ('T1 →' T2 → bool) → 'T1 список →' T2 список → bool | Проверяет, все ли соответствующие элементы коллекции попарно удовлетворяют заданному предикату. |
head: 'T список →' T | Возвращает первый элемент списка. |
init: int → (int → 'T) →' T список | Создает список, вызывая данный генератор для каждого индекса. |
isEmpty: 'T список → bool | Возврат true если список не содержит элементов, false иначе. |
iter: ('T → единица) →' T список → единица | Применяет данную функцию к каждому элементу коллекции. |
iter2: ('T1 →' T2 → unit) → 'T1 list →' T2 list → unit | Применяет данную функцию к двум коллекциям одновременно. Коллекции должны быть одинакового размера. |
iteri: (int → 'T → unit) →' T список → unit | Применяет данную функцию к каждому элементу коллекции. Целое число, переданное в функцию, указывает индекс элемента. |
iteri2: (int → 'T1 →' T2 → unit) → 'T1 list →' T2 list → unit | Применяет данную функцию к двум коллекциям одновременно. Коллекции должны быть одинакового размера. Целое число, переданное в функцию, указывает индекс элемента. |
длина: 'T список → int | Возвращает длину списка. |
карта: ('T →' U) → 'T список →' U список | Создает новую коллекцию, элементы которой являются результатом применения данной функции к каждому из элементов коллекции. |
map2: ('T1 →' T2 → 'U) →' T1 список → 'T2 список →' U список | Создает новую коллекцию, элементы которой являются результатами попарного применения данной функции к соответствующим элементам двух коллекций. |
map3: ('T1 →' T2 → 'T3 →' U) → 'T1 список →' T2 список → 'T3 список →' U список | Создает новую коллекцию, элементы которой являются результатами применения данной функции одновременно к соответствующим элементам трех коллекций. |
mapi: (int → 'T →' U) → 'T список →' U список | Создает новую коллекцию, элементы которой являются результатом применения данной функции к каждому из элементов коллекции. Целочисленный индекс, переданный в функцию, указывает индекс (от 0) преобразуемого элемента. |
mapi2: (int → 'T1 →' T2 → 'U) →' T1 список → 'T2 список →' U список | Подобно List.mapi, но отображает соответствующие элементы из двух списков равной длины. |
max: 'T список →' T | Возвращает наибольший из всех элементов списка, по сравнению с использованием Operators.max. |
maxBy: ('T →' U) → 'T список →' T | Возвращает наибольший из всех элементов списка, по сравнению с использованием Operators.max для результата функции. |
min: 'T список →' T | Возвращает самый низкий из всех элементов списка, по сравнению с использованием Operators.min. |
minBy: ('T →' U) → 'T список →' T | Возвращает самый низкий из всех элементов списка, по сравнению с использованием Operators.min в результате функции. |
nth: 'T список → int →' T | Индексы в список. Первый элемент имеет индекс 0. |
ofArray: 'T [] →' T список | Создает список из заданного массива. |
ofSeq: seq <'T> →' T список | Создает новый список из заданного перечислимого объекта. |
раздел: ('T → bool) →' T список * 'T список | Разделяет коллекцию на две коллекции, содержащие элементы, для которых данный предикат возвращает true и false соответственно. |
перестановка: (int → int) → 'T список →' T список | Возвращает список со всеми элементами, переставленными в соответствии с указанной перестановкой. |
выберите: ('T →' U опция) → 'T список →' U | Применяет данную функцию к последовательным элементам, возвращая первый результат, в котором функция возвращает Some за некоторую стоимость. |
уменьшить: ('T →' T → 'T) →' T список → 'T | Применяет функцию к каждому элементу коллекции, передавая аргумент аккумулятора через вычисление. Эта функция применяет указанную функцию к первым двум элементам списка. Затем он передает этот результат в функцию вместе с третьим элементом и так далее. Наконец, он возвращает окончательный результат. Если входная функция - f, а элементы - i0 ... iN, то эта функция вычисляет f (... (f i0 i1) i2 ...) iN. |
reduceBack: ('T →' T → 'T) →' T список → 'T | Применяет функцию к каждому элементу коллекции, передавая аргумент аккумулятора через вычисление. Если входная функция равна f, а элементы - i0 ... iN, то эта функция вычисляет f i0 (... (f iN-1 iN)). |
реплицировать: (int → 'T →' T список) | Создает список, вызывая данный генератор для каждого индекса. |
rev: 'T список →' T список | Возвращает новый список с элементами в обратном порядке. |
сканирование: ('Состояние →' T → 'Состояние) →' Состояние → 'Список T →' Список состояний | Применяет функцию к каждому элементу коллекции, передавая аргумент аккумулятора через вычисление. Эта функция принимает второй аргумент и применяет указанную функцию к нему и первому элементу списка. Затем он передает этот результат в функцию вместе со вторым элементом и так далее. Наконец, он возвращает список промежуточных результатов и окончательный результат. |
scanBack: ('T →' Состояние → 'Состояние) →' T-список → 'Состояние →' Список состояний | Подобен foldBack, но возвращает как промежуточные, так и окончательные результаты |
sort: 'T список →' T список | Сортирует указанный список с помощью Operators.compare. |
sortBy: ('T →' Key) → 'T список →' T список | Сортирует данный список с использованием ключей, заданных данной проекцией. Ключи сравниваются с помощью Operators.compare. |
sortWith: ('T →' T → int) → 'T список →' T список | Сортирует данный список, используя данную функцию сравнения. |
сумма: ^ T список → ^ T | Возвращает сумму элементов в списке. |
sumBy: ('T → ^ U) →' T список → ^ U | Возвращает сумму результатов, полученных при применении функции к каждому элементу списка. |
хвост: 'T список →' T список | Возвращает список ввода без первого элемента. |
toArray: 'T список →' T [] | Создает массив из заданного списка. |
toSeq: 'T список → seq <' T> | Рассматривает данный список как последовательность. |
tryFind: ('T → bool) →' T список → 'T вариант | Возвращает первый элемент, для которого данная функция возвращает true. ВозвращениеNone если такого элемента нет. |
tryFindIndex: ('T → bool) →' T список → параметр int | Возвращает индекс первого элемента в списке, который удовлетворяет заданному предикату. ВозвращениеNone если такого элемента нет. |
tryPick: ('T →' U опция) → 'T список →' U опция | Применяет данную функцию к последовательным элементам, возвращая первый результат, в котором функция возвращает Someза некоторую стоимость. Если такого элемента нет, вернитеNone. |
распаковать: ('T1 *' T2) список → 'T1 список *' T2 список | Разбивает список пар на два списка. |
unzip3: ('T1 *' T2 * 'T3) list →' T1 list * 'T2 list *' T3 list | Разбивает список троек на три списка. |
zip: 'Список T1 → Список T2 → (' T1 * 'T2) список | Объединяет два списка в список пар. Два списка должны иметь одинаковую длину. |
zip3: 'Список T1 → Список T2 → Список T3 → (' 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 ])
Когда вы компилируете и выполняете программу, она дает следующий результат:
Sum of the elements of list [1; 2; 3; 4; 5; 6; 7; 8; 9; 10] is 55.