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.