Значение последнего элемента списка
Как получить значение последнего элемента списка? Я заметила этот список.hd (или .Head) возвращает элемент, в то время как список.tl (or .Tail) возвращает список.
является ли rev список и получить hd единственный способ обойти? Спасибо.
10 ответов
попробовать эту функцию. Он использует рекурсию, хотя она оптимизируется для итерации в любом случае, так как это хвостовая рекурсия. В любом случае, это, скорее всего, быстрее, чем перевернуть весь список (используя List.rev
).
let rec last = function
| hd :: [] -> hd
| hd :: tl -> last tl
| _ -> failwith "Empty list."
ответ Павла Минаева, безусловно, стоит принять во внимание, однако. Тем не менее, алгоритм, который вы запросили, может быть полезен в некоторых редких случаях и является наиболее эффективным способом выполнения задачи.
В общем, если вам это нужно, вы делаете что-то неправильно. Поскольку списки F# являются односвязными, доступ к последнему элементу стоит дорого -O(N)
, где N-размер list
. Попробуйте переписать свой алгоритм так, чтобы вы всегда обращались к первый элемент, не последний (который является O(1)
). Если вы не можете этого сделать, велики шансы, что ваш выбор list
для структуры данных не является правильным в первую очередь.
быстрый и грязный способ сделать это, используя список.уменьшить. Предполагая, что список называется ls
,
let lastElement ls = List.reduce (fun _ i -> i) ls
что касается эффективности, я согласен с Павлом.
более краткая версия, основанная на ответе Митча:
let lastItem = myList |> List.rev |> List.head
на myList
список отправлено
согласен, не так эффективно получить последний элемент 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
вы можете назвать список.Head, чтобы получить первый элемент списка, такой, что приведенное ниже выражение оценивается как true:
let lst = [1;2;3;4;5]
List.head lst = 1
однако, список вызовов.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