Помощничек
Главная | Обратная связь


Археология
Архитектура
Астрономия
Аудит
Биология
Ботаника
Бухгалтерский учёт
Войное дело
Генетика
География
Геология
Дизайн
Искусство
История
Кино
Кулинария
Культура
Литература
Математика
Медицина
Металлургия
Мифология
Музыка
Психология
Религия
Спорт
Строительство
Техника
Транспорт
Туризм
Усадьба
Физика
Фотография
Химия
Экология
Электричество
Электроника
Энергетика

Работа с несколькими списками.



Списки могут быть объединены. Чтобы объединить два списка в один, используется функция List.append. Чтобы объединить больше двух списков, используется функция List.concat.

let list1to10 = List.append [1; 2; 3] [4; 5; 6; 7; 8; 9; 10]

let listResult = List.concat [ [1; 2; 3]; [4; 5; 6]; [7; 8; 9] ]

List.iter (fun elem -> printf "%d " elem) list1to10

printfn ""

List.iter (fun elem -> printf "%d " elem) listResult

Операции сворачивания и сканирования похожи на функции List.iter и List.map в том, что функция вызывается по каждому элементу, но включают дополнительный параметр, который называется аккумулятор и содержит результат вычисления. List.fold можно использовать для выполнения расчетов со списком.

В следующем коде показано использование функции List.fold для выполнения различных операций. Лист обходится. Аккумулятор acc — это значение, которое передается дальше, пока продолжается расчет. Первый аргумент забирает аккумулятор и элемент списка и возвращает промежуточный результат расчета для этого элемента списка. Второй аргумент является исходным значением аккумулятора.

let sumList list = List.fold (fun acc elem -> acc + elem) 0 list

printfn "Sum of the elements of list %A is %d." [ 1 .. 3 ] (sumList [ 1 .. 3 ])

let averageList list = (List.fold (fun acc elem -> acc + float elem) 0.0 list / float list.Length)

let stdDevList list =

let avg = averageList list

sqrt (List.fold (fun acc elem -> acc + (float elem - avg) ** 2.0 ) 0.0 list / float list.Length)

let testList listTest =

printfn "List %A average: %f stddev: %f" listTest (averageList listTest) (stdDevList listTest)

testList [1; 1; 1]

testList [1; 2; 1]

testList [1; 2; 3]

let printList list = List.fold (fun acc elem -> printfn "%A" elem) () list

printList [0.0; 1.0; 2.5; 5.1 ]

 

let reverseList list = List.fold (fun acc elem -> elem::acc) [] list

printfn "%A" (reverseList [1 .. 10])

Версии этих функций с цифрой в имени функции работают с несколькими списками. Например, функция List.fold2 осуществляет расчет с двумя списками.

В следующем примере показано использование функции List.fold2:

let sumGreatest list1 list2 = List.fold2 (fun acc elem1 elem2 ->

acc + max elem1 elem2) 0 list1 list2

let sum = sumGreatest [1; 2; 3] [3; 2; 1]

printfn "The sum of the greater of each pair of elements in the two lists is %d." sum

Функция List.scan отличается тем, что List.fold возвращает конечное значение дополнительного параметра, а List.scan — список промежуточных значений (наравне с конечным значением) дополнительного параметра. Каждая из этих функций включает обратную вариацию, например List.foldBack, и отличается в порядке обхода списка и в порядке аргументов. Кроме того, функции List.fold и List.foldBack имеют вариации, List.fold2 и List.foldBack2, которые берут два списка одинаковой длины. Функция, которая выполняется по каждому элементу, может использовать соответствующие элементы обоих списков для выполнения некоторых действий. Типы элементов этих списков могут отличаться, как в следующем примере, где один список содержит суммы транзакций на банковском счете, а другой — типы транзакций (внесение или снятие).

type Transaction =

| Deposit

| Withdrawal

let transactionTypes = [Deposit; Deposit; Withdrawal]

let transactionAmounts = [100.00; 1000.00; 95.00 ]

let initialBalance = 200.00

let endingBalance = List.fold2 (fun acc elem1 elem2 ->

match elem1 with

| Deposit -> acc + elem2

| Withdrawal -> acc - elem2)

initialBalance

transactionTypes

transactionAmounts

printfn "%f" endingBalance

При расчете суммы функции List.fold и List.foldBack действуют одинаково, так как результат не зависит от порядка обхода. В следующем примере кода функцияList.foldBack используется для добавления элемента в список.

let sumListBack list = List.foldBack (fun acc elem -> acc + elem) list 0

printfn "%d" (sumListBack [1; 2; 3])

let copyList list = List.foldBack (fun elem acc -> elem::acc) list []

printfn "%A" (copyList [1 .. 10])

В следующем примере снова используется банковский счет. В этот раз добавляется новый тип транзакций: расчет процентов. Конечный баланс теперь зависит от порядка транзакций.

type Transaction2 =

| Deposit

| Withdrawal

| Interest

let transactionTypes2 = [Deposit; Deposit; Withdrawal; Interest]

let transactionAmounts2 = [100.00; 1000.00; 95.00; 0.05 / 12.0 ]

let initialBalance2 = 200.00

let endingBalance2 = List.fold2 (fun acc elem1 elem2 ->

match elem1 with

| Deposit -> acc + elem2

| Withdrawal -> acc - elem2

| Interest -> acc * (1.0 + elem2))

initialBalance2

transactionTypes2

transactionAmounts2

printfn "%f" endingBalance2

let endingBalance3 = List.foldBack2 (fun elem1 elem2 acc ->

match elem1 with

| Deposit -> acc + elem2

| Withdrawal -> acc - elem2

| Interest -> acc * (1.0 + elem2))

transactionTypes2

transactionAmounts2

initialBalance2

printfn "%f" endingBalance3

Функция List.reduce похожа на функцию List.fold и List.scan за тем исключением, что вместо передачи отдельного аккумулятора List.reduce использует функцию, которая берет два аргумента типа элемента вместо одного, и один из таких аргументов играет роль аккумулятора, т. е. хранит промежуточный результат вычисления.List.reduce начинает работу с первых двух элементов списка, а затем использует результат операции вместе со следующим элементом. Так как здесь нет отдельного аккумулятора с собственным типом, функция List.reduce может использоваться вместо List.fold только в том случае, если аккумулятор и элемент имеют одинаковые типы. В следующем коде показано использование функции List.reduce. List.reduce выводит исключение, если в списке нет элементов.

В следующем коде первый вызов выражения лямбда дает аргументы 2 и 4 и возвращает 6. В следующем вызове даются аргументы 6 и 10 и возвращается результат 16.

let sumAList list =

try

List.reduce (fun acc elem -> acc + elem) list

with

| :? System.ArgumentException as exc -> 0

let resultSum = sumAList [2; 4; 10]

printfn "%d " resultSum

 




Поиск по сайту:

©2015-2020 studopedya.ru Все права принадлежат авторам размещенных материалов.