Pregunta

cómo obtener el valor del último elemento de una lista? He observado que List.hd (o .Head) devolver un artículo, mientras que List.tl (o .Tail) devuelve una lista.

Se rev la lista y obtener el hd la única manera de evitar? Gracias.

¿Fue útil?

Solución

Trate de esta función. Se utiliza la recursividad, a pesar de que se ha optimizado para la iteración de todos modos, ya que de recursión de cola. En cualquier caso, lo más probable es más rápido que la inversión de la lista entera (usando List.rev).

let rec last = function
    | hd :: [] -> hd
    | hd :: tl -> last tl
    | _ -> failwith "Empty list."

La respuesta de Pavel Minaev es definitivamente vale la pena teniendo en cuenta, sin embargo. Sin embargo, el algoritmo que ha solicitado puede ser útil en algunos casos raros, y es la forma más eficiente para ir sobre la tarea.

Otros consejos

En general, si usted tiene que hacer esto, estás haciendo algo mal. Desde F # listas son simplemente enlazada, acceder el último elemento es costoso - O(N), donde N es el tamaño de list. Tratar de reescribir su algoritmo para que siempre acceder al primer elemento de , no el último (que es O(1)). Si no puede hacerlo, es muy probable que la elección de list para una estructura de datos no era correcta en el primer lugar.

Una forma rápida y sucia de hacerlo es mediante el uso de List.reduce. Suponiendo que la lista se llama ls,

let lastElement ls = List.reduce (fun _ i -> i) ls

En cuanto a la eficiencia, estoy de acuerdo con Pavel.

Una versión más concisa sobre la base de la respuesta de Mitch:

let lastItem = myList |> List.rev |> List.head

La lista myList se envía a la función List.rev. El resultado es entonces procesada por List.head

De acuerdo, no es tan eficiente para obtener el último elemento de list, o cualquier otra secuencia "numerable". Dicho esto, esta función ya existe en el módulo Seq, Seq.last.

Como un novato F # desarrollador, no veo lo que el daño está en hacer lo siguiente

let mylist = [1;2;3;4;5]

let lastValue = mylist.[mylist.Length - 1]

imperativo en la naturaleza? Sí, pero no hay necesidad de recursividad.

La forma regular para trabajar con listas en F # es el uso de la recursividad. El primer elemento de la lista es la cabeza (obviamente) y el resto de la lista es la cola (como se oponen a la última opción). Por eso, cuando una función recieves una lista que procesa la cabeza y luego procesa de forma recursiva el resto de la lista ( cola ).

let reversedList = List.rev originalList
let tailItem = List.hd reversedList

Creo que se puede escribir

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

Puede llamar List.Head para obtener el primer elemento de una lista, de manera que la siguiente expresión se evalúa como verdadera:

let lst = [1;2;3;4;5]
List.head lst = 1

Sin embargo, llamando List.Tail volverá cada elemento de la lista después el primer elemento, de tal manera que la expresión a continuación es verdadera:

let lst = [1;2;3;4;5]
List.tail lst = [2;3;4;5]

Al igual que otras personas han mencionado, no es una forma eficiente de F # para obtener el final de una lista, listas básicas no están construidos con esa funcionalidad en mente. Si realmente desea obtener el último elemento que va a tener que invertir su lista primero, y luego tomar el nuevo jefe (que era la cola anterior).

let lst = [1;2;3;4;5]
(List.head (List.rev lst) ) = 5

A continuación código trabajó bien para mí, tengo una matriz de enteros, que desee comenzar desde el punto quinto, luego se lo menos el número de artículo

Sum of [Array(xi) - Array(xi-5)] where i start at 5

El código utilizado es:

series |> Array.windowed 5
       |> Array.fold (fun s x -> 
                            (x |> Array.rev |> Array.head) -  (x |> Array.head) + s) 0
       |> float
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top