Значение последнего элемента списка
Вопрос
как получить значение последнего элемента списка?Я заметил, что List.hd (или .Head) возвращает элемент, а List.tl (или .Tail) возвращает список.
Является ли пересмотр списка и получение hd единственным выходом?Спасибо.
Решение
Попробуйте эту функцию.Он использует рекурсию, хотя в любом случае он оптимизируется для итерации, поскольку это хвостовая рекурсия.В любом случае, это, скорее всего, быстрее, чем переворачивать весь список (используя List.rev
).
let rec last = function
| hd :: [] -> hd
| hd :: tl -> last tl
| _ -> failwith "Empty list."
Однако ответ Павла Минаева, безусловно, стоит принять во внимание.Тем не менее, запрошенный вами алгоритм может быть полезен в некоторых редких случаях и является наиболее эффективным способом решения задачи.
Другие советы
В общем, если вам нужно это сделать, вы что-то делаете не так.Поскольку списки F# являются односвязными, доступ к последнему элементу является дорогостоящим. O(N)
, где N — размер list
.Попробуйте переписать свой алгоритм так, чтобы всегда иметь доступ к первый элемент, а не последний (который O(1)
).Если вы не можете этого сделать, велика вероятность, что ваш выбор list
поскольку структура данных изначально была неправильной.
Быстрый и грязный способ сделать это — использовать List.reduce.Предполагая, что список называется ls
,
let lastElement ls = List.reduce (fun _ i -> i) ls
Насчет эффективности согласен с Павлом.
Более краткая версия, основанная на ответе Митча:
let lastItem = myList |> List.rev |> List.head
А myList
список отправляется на List.rev
функция.Затем результат обрабатывается List.head
Согласен, не так эффективно получить последний элемент list
, или любую другую «перечислимую» последовательность.Тем не менее, эта функция уже существует в Seq
модуль, Seq.last
.
Как начинающий F#-разработчик, я не вижу вреда в следующем:
let mylist = [1;2;3;4;5]
let lastValue = mylist.[mylist.Length - 1]
Императивный характер?Да, но нет необходимости в рекурсии.
Обычный способ работы со списками в F# — использование рекурсии.Первый элемент списка — это голова (очевидно), а остальная часть списка — хвост (в отличие от последнего элемента).Поэтому, когда функция получает список, она обрабатывает голова а затем рекурсивно обрабатывает остальную часть списка ( хвост).
let reversedList = List.rev originalList
let tailItem = List.hd reversedList
Я думаю, ты можешь просто написать
list.[0..list.Length-1]
Вы можете вызвать List.Head, чтобы получить первый элемент списка, чтобы приведенное ниже выражение имело значение true:
let lst = [1;2;3;4;5]
List.head lst = 1
Однако вызов List.Tail вернет каждый элемент списка. после первый элемент, так что приведенное ниже выражение истинно:
let lst = [1;2;3;4;5]
List.tail lst = [2;3;4;5]
Как уже упоминали некоторые другие люди, в F # не существует эффективного способа получить конец списка, базовые списки просто не создаются с учетом этой функциональности.Если вы действительно хотите получить последний элемент, вам придется сначала перевернуть список, а затем взять новую голову (которая была предыдущим хвостом).
let lst = [1;2;3;4;5]
(List.head (List.rev lst) ) = 5
Код ниже работал у меня нормально, у меня есть массив целых чисел, я хочу начать с 5-го элемента, а затем вычесть его номер элемента.
Sum of [Array(xi) - Array(xi-5)] where i start at 5
Используемый код:
series |> Array.windowed 5
|> Array.fold (fun s x ->
(x |> Array.rev |> Array.head) - (x |> Array.head) + s) 0
|> float