Значение последнего элемента списка

Как получить значение последнего элемента списка? Я заметила этот список.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

Я думаю, вы можете просто написать

list.[0..list.Length-1]

вы можете назвать список.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