Domanda

come ottenere il valore dell'ultimo elemento di una lista?Ho notato che List.hd (o .Head) restituisce un elemento, mentre List.tl (o .Tail) restituisce un List.

Rivedere l'elenco e ottenere l'hd è l'unico modo per aggirare il problema?Grazie.

È stato utile?

Soluzione

Prova questa funzione. Esso utilizza ricorsione, anche se viene ottimizzato per iterazione comunque poiché è ricorsione in coda. In ogni caso, è molto probabile che più veloce di invertire l'intero elenco (utilizzando List.rev).

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

La risposta di Pavel Minaev è sicuramente la pena di prendere in considerazione, però. Tuttavia, l'algoritmo hai richiesto può essere utile in alcuni rari casi, ed è il modo più efficace per andare circa il compito.

Altri suggerimenti

In generale, se avete bisogno di fare questo, si sta facendo qualcosa di sbagliato. Dal momento che F # liste sono single-linked, l'accesso l'ultimo elemento è costoso - O(N), dove N è la dimensione di list. Prova a riscrivere l'algoritmo in modo che si accede sempre la prima elemento, non l'ultimo (che è O(1)). Se non è possibile farlo, ci sono buone probabilità che la scelta del list per una struttura di dati non era corretta, in primo luogo.

Un modo rapido e sporco di farlo è quello di utilizzare List.reduce. Supponendo che la lista si chiama ls,

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

Per quanto riguarda l'efficienza, sono d'accordo con Pavel.

Una versione più concisa in base alla risposta di Mitch:

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

La lista myList viene inviato a List.rev funzione. Il risultato viene poi elaborato dal List.head

D'accordo, non è così efficiente per ottenere l'ultimo elemento della list, o di qualsiasi altra sequenza "enumerabile". Che detto, questa funzione è già presente nel modulo Seq, Seq.last.

Come un novizio F # sviluppatore, non vedo ciò che il danno è nel fare il seguente

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

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

imperativo in natura? Sì, ma senza bisogno di ricorsione.

Il modo normale per lavorare con gli elenchi in F# consiste nell'usare la ricorsione.Il primo elemento di una lista è la testa (ovviamente) e il resto della lista è la coda (a differenza dell'ultimo elemento).Pertanto, quando una funzione riceve un elenco, elabora il file Testa e quindi elabora ricorsivamente il resto dell'elenco (the coda).

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

Credo che si può solo scrivere

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

È possibile chiamare List.Head per ottenere il primo elemento di una lista, in modo tale che l'espressione di seguito restituisce true:

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

Tuttavia, chiamando List.Tail tornerà ogni elemento della lista dopo il primo elemento, in modo tale che l'espressione di seguito è vero:

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

Come alcune altre persone hanno detto, non c'è un modo efficiente in F # per ottenere la fine della coda di un elenco, gli elenchi di base semplicemente non sono costruite con tale funzionalità in mente. Se davvero si vuole ottenere l'ultimo elemento che si sta andando ad avere per invertire la vostra lista prima, e poi prendere il nuovo capo (che era la coda precedente).

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

Di seguito il codice ha funzionato bene con me, ho un array di interi, vuole iniziare dal 5 ° elemento, poi prendere meno il numero di articolo

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

Il codice utilizzato è il seguente:

series |> Array.windowed 5
       |> Array.fold (fun s x -> 
                            (x |> Array.rev |> Array.head) -  (x |> Array.head) + s) 0
       |> float
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top