F # - Массивы

Массивы - это изменяемые коллекции фиксированного размера с отсчетом от нуля последовательных элементов данных одного типа.

Создание массивов

Вы можете создавать массивы, используя различные синтаксисы и способы или используя функции из модуля Array. В этом разделе мы обсудим создание массивов без использования функций модуля.

Есть три синтаксических способа создания массивов без функций:

  • Путем перечисления последовательных значений между [| и |] через точку с запятой.
  • Помещая каждый элемент в отдельную строку, и в этом случае разделитель точкой с запятой не является обязательным.
  • Используя выражения последовательности.

Вы можете получить доступ к элементам массива, используя оператор точки (.) И скобки ([и]).

В следующем примере демонстрируется создание массивов -

//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" "

Когда вы компилируете и выполняете программу, она дает следующий результат:

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

Основные операции с массивами

Библиотечный модуль Microsoft.FSharp.Collections.Array поддерживает операции с одномерными массивами.

В следующей таблице показаны основные операции с массивами -

Значение Описание
добавить: 'T [] →' T [] → 'T [] Создает массив, содержащий элементы одного массива, за которыми следуют элементы другого массива.
среднее: ^ T [] → ^ T Возвращает среднее значение элементов в массиве.
meanBy: ('T → ^ U) →' T [] → ^ U Возвращает среднее значение элементов, сгенерированных применением функции к каждому элементу массива.
blit: 'T [] → int →' T [] → int → int → unit Считывает диапазон элементов из одного массива и записывает их в другой.
выберите: ('T → U опция) →' T [] → 'U [] Применяет предоставленную функцию к каждому элементу массива. Возвращает массив, содержащий результаты x для каждого элемента, для которого функция возвращает Some (x).
собрать: ('T →' U []) → T [] → 'U [] Применяет предоставленную функцию к каждому элементу массива, объединяет результаты и возвращает объединенный массив.
concat: seq <'T []> →' T [] Создает массив, содержащий элементы каждой из предоставленных последовательностей массивов.
копировать: 'T →' T [] Создает массив, содержащий элементы предоставленного массива.
создать: int → 'T →' T [] Создает массив, все элементы которого изначально являются предоставленным значением.
пусто: 'T [] Возвращает пустой массив заданного типа.
существует: ('T → bool) →' T [] → bool Проверяет, удовлетворяет ли какой-либо элемент массива указанному предикату.
существует2: ('T1 →' T2 → bool) → 'T1 [] →' T2 [] → bool Проверяет, удовлетворяет ли любая пара соответствующих элементов двух массивов заданному условию.
заполнить: 'T [] → int → int →' T → unit Заполняет диапазон элементов массива предоставленным значением.
фильтр: ('T → bool) →' T [] → 'T [] Возвращает коллекцию, содержащую только элементы предоставленного массива, для которых предоставленное условие возвращает true.
найти: ('T → bool) →' T [] → 'T Возвращает первый элемент, для которого предоставленная функция возвращает true. Вызывает исключение KeyNotFoundException, если такой элемент не существует.
findIndex: ('T → bool) →' T [] → int Возвращает индекс первого элемента в массиве, который удовлетворяет заданному условию. Вызывает исключение KeyNotFoundException, если ни один из элементов не удовлетворяет условию.
свёртка: ('Состояние →' T → 'Состояние) →' Состояние → 'T [] →' Состояние Применяет функцию к каждому элементу массива, передавая аргумент аккумулятора через вычисление. Если входная функция - f, а элементы массива - i0 ... iN, эта функция вычисляет f (... (fs i0) ...) iN.
fold2: ('Состояние →' T1 → 'T2 →' Состояние) → 'Состояние →' T1 [] → 'T2 [] →' Состояние Применяет функцию к парам элементов из двух предоставленных массивов слева направо, передавая аргумент аккумулятора через вычисления. Два входных массива должны иметь одинаковую длину; в противном случае возникает исключение ArgumentException.
foldBack: ('T →' Состояние → 'Состояние) →' T [] → 'Состояние →' Состояние Применяет функцию к каждому элементу массива, передавая аргумент аккумулятора через вычисление. Если входная функция - f, а элементы массива - i0 ... iN, эта функция вычисляет f i0 (... (f iN s)).
foldBack2: ('T1 →' T2 → 'State →' State) → 'T1 [] →' T2 [] → 'State →' Состояние Применяет функцию к парам элементов из двух предоставленных массивов справа налево, передавая аргумент аккумулятора через вычисление. Два входных массива должны иметь одинаковую длину; в противном случае возникает исключение ArgumentException.
forall: ('T → bool) →' T [] → bool Проверяет, все ли элементы массива удовлетворяют заданному условию.
forall2: ('T1 →' T2 → bool) → 'T1 [] →' T2 [] → bool Проверяет, удовлетворяют ли все соответствующие элементы двух предоставленных массивов поставленному условию.
получить: 'T [] → int →' T Получает элемент из массива.
init: int → (int → 'T) →' T [] Использует предоставленную функцию для создания массива предоставленного измерения.
isEmpty: 'T [] → bool Проверяет, есть ли в массиве какие-либо элементы.
iter: ('T → единица) →' T [] → единица Применяет предоставленную функцию к каждому элементу массива.
iter2: ('T1 →' T2 → блок) → 'T1 [] →' T2 [] → блок) Применяет предоставленную функцию к паре элементов из совпадающих индексов в двух массивах. Два массива должны иметь одинаковую длину; в противном случае возникает исключение ArgumentException.
iteri: (int → 'T → unit) →' T [] → unit Применяет предоставленную функцию к каждому элементу массива. Целое число, переданное в функцию, указывает индекс элемента.
iteri2: (int → 'T1 →' T2 → unit) → 'T1 [] →' T2 [] → unit Применяет предоставленную функцию к паре элементов из совпадающих индексов в двух массивах, также передавая индекс элементов. Два массива должны иметь одинаковую длину; в противном случае возникает исключение ArgumentException.
длина: 'T [] → int Возвращает длину массива. Свойство Length делает то же самое.
карта: ('T →' U) → 'T [] →' U [] Создает массив, элементы которого являются результатом применения предоставленной функции к каждому из элементов предоставленного массива.
map2: ('T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] Создает массив, элементы которого являются результатом применения предоставленной функции к соответствующим элементам двух предоставленных массивов. Два входных массива должны иметь одинаковую длину; в противном случае возникает исключение ArgumentException.
mapi: (int → 'T →' U) → 'T [] →' U [] Создает массив, элементы которого являются результатом применения предоставленной функции к каждому из элементов предоставленного массива. Целочисленный индекс, переданный в функцию, указывает индекс преобразуемого элемента.
mapi2: (int → 'T1 →' T2 → 'U) →' T1 [] → 'T2 [] →' U [] Создает массив, элементы которого являются результатами попарного применения предоставленной функции к соответствующим элементам двух коллекций, также передавая индекс элементов. Два входных массива должны иметь одинаковую длину; в противном случае возникает исключение ArgumentException.
макс: 'T [] →' T Возвращает наибольший из всех элементов массива. Operators.max используется для сравнения элементов.
maxBy: ('T →' U) → 'T [] →' T Возвращает наибольший из всех элементов массива по сравнению с помощью Operators.max в результате функции.
мин: ('T [] →' T Возвращает наименьший из всех элементов массива. Operators.min используется для сравнения элементов.
minBy: ('T →' U) → 'T [] →' T Возвращает наименьший из всех элементов массива. Operators.min используется для сравнения элементов.
ofList: 'T список →' T [] Создает массив из предоставленного списка.
ofSeq: seq <'T> →' T [] Создает массив из предоставленного перечислимого объекта.
раздел: ('T → bool) →' T [] → 'T [] *' T [] Разделяет массив на два массива, один из которых содержит элементы, для которых предоставленное условие возвращает true, а другой содержит те, для которых он возвращается false.
перестановка: (int → int) → 'T [] →' T [] Переставляет элементы массива в соответствии с указанной перестановкой.
выберите: ('T →' U опция) → 'T [] →' U Применяет предоставленную функцию к последовательным элементам предоставленного массива, возвращая первый результат, где функция возвращает Some (x) для некоторого x. Если функция никогда не возвращает Some (x), возникает исключение KeyNotFoundException.
уменьшить: ('T →' T → 'T) →' T [] → 'T Применяет функцию к каждому элементу массива, передавая аргумент аккумулятора через вычисление. Если входная функция - f, а элементы массива - i0 ... iN, эта функция вычисляет f (... (f i0 i1) ...) iN. Если размер массива равен нулю, возникает исключение ArgumentException.
reduceBack: ('T →' T → 'T) →' T [] → 'T Применяет функцию к каждому элементу массива, передавая аргумент аккумулятора через вычисление. Если входная функция - f, а элементы - i0 ... iN, эта функция вычисляет f i0 (... (f iN-1 iN)). Если размер массива равен нулю, возникает исключение ArgumentException.
rev: 'T [] →' T [] Изменяет порядок элементов в предоставленном массиве.
сканирование: ('Состояние →' T → 'Состояние) →' Состояние → 'T [] →' Состояние []) Действует как fold, но возвращает промежуточные результаты вместе с окончательными.
scanBack: ('T →' Состояние → 'Состояние) →' T [] → 'Состояние →' Состояние [] Действует как foldBack, но возвращает промежуточные результаты вместе с окончательными.
установить: 'T [] → int →' T → unit Устанавливает элемент массива.
сортировать: 'T [] →' T [] Сортирует элементы массива и возвращает новый массив. Operators.compare используется для сравнения элементов.
sortBy: ('T →' Key) → 'T [] →' T [] Сортирует элементы массива, используя предоставленную функцию для преобразования элементов в тип, на котором основана операция сортировки, и возвращает новый массив. Operators.compare используется для сравнения элементов.
sortInPlace: 'T [] → unit Сортирует элементы массива, изменяя массив на месте, используя предоставленную функцию сравнения. Operators.compare используется для сравнения элементов.
sortInPlaceBy: ('T →' Key) → 'T [] → unit Сортирует элементы массива, изменяя массив на месте, используя предоставленную проекцию для ключей. Operators.compare используется для сравнения элементов.
sortInPlaceWith: ('T →' T → int) → 'T [] → unit Сортирует элементы массива, используя предоставленную функцию сравнения для изменения массива на месте.
sortWith: ('T →' T → int) → 'T [] →' T [] Сортирует элементы массива с помощью предоставленной функции сравнения и возвращает новый массив.
sub: 'T [] → int → int →' T [] Создает массив, содержащий предоставленный поддиапазон, который определяется начальным индексом и длиной.
сумма: 'T [] → ^ T Возвращает сумму элементов в массиве.
sumBy: ('T → ^ U) →' T [] → ^ U Возвращает сумму результатов, полученных при применении функции к каждому элементу массива.
toList: 'T [] →' T список Преобразует предоставленный массив в список.
toSeq: 'T [] → seq <' T> Рассматривает предоставленный массив как последовательность.
tryFind: ('T → bool) →' T [] → 'T опция Возвращает первый элемент в предоставленном массиве, для которого предоставленная функция возвращает true. ВозвратNone если такого элемента нет.
tryFindIndex: ('T → bool) →' T [] → параметр int Возвращает индекс первого элемента в массиве, который удовлетворяет заданному условию.
tryPick: ('T →' U опция) → 'T [] →' U опция Применяет предоставленную функцию к последовательным элементам предоставленного массива и возвращает первый результат, в котором функция возвращает Some (x) для некоторого x. Если функция никогда не возвращает Some (x),None возвращается.
разархивировать: ('T1 *' T2) [] → 'T1 [] *' T2 [] Разбивает массив пар кортежей на кортеж из двух массивов.
unzip3: ('T1 *' T2 * 'T3) [] →' T1 [] * 'T2 [] *' T3 [] Разбивает массив кортежей из трех элементов на кортеж из трех массивов.
zeroCreate: int → 'T [] Создает массив, для элементов которого изначально задано значение по умолчанию Unchecked.defaultof <'T>.
zip: 'T1 [] →' T2 [] → ('T1 *' T2) [] Объединяет два массива в массив кортежей, состоящих из двух элементов. Два массива должны иметь одинаковую длину; в противном случае возникает исключение ArgumentException.
zip3: 'T1 [] →' T2 [] → 'T3 [] → (' T1 * 'T2 * 113' T3) [] Объединяет три массива в массив кортежей, состоящих из трех элементов. Три массива должны иметь одинаковую длину; в противном случае возникает исключение ArgumentException.

В следующем разделе мы увидим использование некоторых из этих функций.

Создание массивов с использованием функций

Модуль Array предоставляет несколько функций, которые создают массив с нуля.

  • В Array.empty функция создает новый пустой массив.

  • В Array.create Функция создает массив указанного размера и устанавливает для всех элементов заданные значения.

  • В Array.init Функция создает массив с заданным размером и функцией для генерации элементов.

  • В Array.zeroCreate Функция создает массив, в котором все элементы инициализируются нулевым значением.

  • В Array.copy Функция создает новый массив, содержащий элементы, скопированные из существующего массива.

  • В Array.sub функция генерирует новый массив из поддиапазона массива.

  • В Array.append функция создает новый массив, объединяя два существующих массива.

  • В Array.choose функция выбирает элементы массива для включения в новый массив.

  • В Array.collect функция запускает указанную функцию для каждого элемента массива существующего массива, а затем собирает элементы, сгенерированные функцией, и объединяет их в новый массив.

  • В Array.concat Функция принимает последовательность массивов и объединяет их в один массив.

  • В Array.filter Функция принимает логическую функцию условия и генерирует новый массив, содержащий только те элементы из входного массива, для которых условие истинно.

  • В Array.rev Функция генерирует новый массив, меняя порядок существующего массива.

Следующие примеры демонстрируют эти функции -

Пример 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

Когда вы компилируете и выполняете программу, она дает следующий результат:

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|]

Пример 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

Когда вы компилируете и выполняете программу, она дает следующий результат:

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|]

Поиск в массивах

В Array.find функция принимает логическую функцию и возвращает первый элемент, для которого функция возвращает истину, иначе вызывает KeyNotFoundException.

В Array.findIndex функция работает аналогично, за исключением того, что она возвращает индекс элемента вместо самого элемента.

Следующий пример демонстрирует это.

Microsoft предоставляет этот интересный пример программы, который находит первый элемент в диапазоне заданного числа, который является как полным квадратом, так и идеальным кубом:

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

Когда вы компилируете и выполняете программу, она дает следующий результат:

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