Qual è il modo più veloce per ottenere l'ultimo elemento di una lista in Haskell. Inoltre nella prossima iterazione, voglio rimuovere il primo e l'ultimo elemento della lista. Qual è il modo più elegante per farlo? Sto provando la comprensione delle liste, ma non sembra molto efficiente!Il modo più veloce per ottenere l'ultimo elemento di una lista in Haskell
risposta
last
e init
faranno il lavoro bene per una tantum. Tuttavia sono entrambi O (n), quindi se è necessario manipolare spesso entrambe le estremità di un elenco, come sembra implicitamente, è consigliabile prendere in considerazione l'utilizzo di Data.Sequence
, che supporta l'inserimento e la rimozione di O (1) di articoli ad entrambe le estremità.
È possibile utilizzare the last
function per ottenere l'ultimo elemento di un elenco.
Per quanto riguarda la rimozione del primo e dell'ultimo elemento, è possibile utilizzare (init . tail)
, ma non so quanto sia efficiente.
Credo che questa immagine da Learn You A Haskell mostra le funzioni della lista abbastanza bene:
Non '' (init. Tail) 'sbagliato/falloso? Dovrebbe essere '(testa a coda)'. – nulvinge
@nulvinge (head. Tail) restituirebbe solo il secondo elemento nell'elenco. Guarda l'immagine sopra :) – Phyx
Ops, mi dispiace, hai ragione. Ultimamente ho fatto molto per riconoscere. come composizione ... – nulvinge
Per rimuovere prima e l'ultima:
take (len(l)-2) (drop 1 l)
o forse
init (drop 1 l)
Questo anche risultati in codice quasi ottimale.
vi posterò la realizzazione Preludio in quanto non è stata ancora spedita:
listLast :: [a] -> a
listLast [x] = x --base case is when there's just one element remaining
listLast (_:xs) = listLast xs --if there's anything in the head, continue until there's one element left
listLast [] = error "Can't do last of an empty list!"
Nota che ho cambiato il nome della funzione di listLast
in modo che possa essere eseguito senza entrare in conflitto con il Preludio normale. Potresti, ovviamente, fare import Prelude hiding(last)
.
La convenzione che usa in questo http://learnyouahaskell.com/chapters è 'last'' – CSharper
(head.reverse) [1..100]
È un'alternativa a last
per ottenere l'ultimo elemento.
drop 1 (take (length [1..100] - 1) [1..100])
rimuove il primo e l'ultimo elemento della lista. La fonte per drop
e take
sembra che potrebbe essere più veloce di (init . tail)
.
(reverse.drop 1) ((reverse.drop 1) [1..100])
è un'altra variante. Ma credo che sia più lento a causa della doppia inversione.
' length' è raramente qualcosa che si vuole fare senza una buona ragione. Non c'è una buona ragione qui. Lo stesso vale per 'reverse'. – dfeuer
Questa risposta si concentra sulla gestione di condizioni strane (come le liste vuote) in un modo massimamente flessibile e sulla creazione di funzioni più grandi da quelle più piccole utilizzando alcune funzioni della libreria. È non la migliore risposta per qualcuno che prima apprende sulle liste, ma piuttosto un paio di passaggi oltre.
Per quanto segue, è necessario
import Control.Monad ((>=>))
e sarà necessario usare sia per GHC 7.10 e importare Data.List (uncons)
o definire
uncons :: [a] -> Maybe (a, [a])
uncons [] = Nothing
uncons (x:xs) = Just (x,xs)
È possibile scrivere una forma sicura di init
come questo:
init' :: [x] -> Maybe [x]
init' = foldr go Nothing
where
go x mxs = Just (maybe [] (x:) mxs)
Una versione di tail
può essere scritto
tail' :: [a] -> Maybe [a]
tail' = fmap snd . uncons
Così allora si può ottenere un forse
trim' :: [a] -> Maybe [a]
trim' = init' >=> tail'
Il >=>
è una sorta di composizione monadica all'indietro. init' >=> tail'
è una funzione che applica init'
al suo argomento per ottenere un valore Maybe [a]
. Se ottiene Nothing
, lo restituisce. Se ottiene Just xs
, applica tail'
a xs
e lo restituisce.
Da questo, si può facilmente fare un trimmer che rifila liste con 0, 1, o 2 elementi verso il basso per le liste vuote:
trim :: [a] -> [a]
trim = maybe [] id . trim'
- 1. Il modo più veloce per trovare un elemento in una lista?
- 2. Modo Pythonic per ottenere l'elemento più grande in una lista
- 3. In Haskell, qual è il modo più comune per applicare una funzione ad ogni ennesimo elemento di una lista?
- 4. Haskell: Esiste un modo idiomatico di inserire ogni elemento in una lista nella propria lista?
- 5. modo veloce di stringhe di attraversamento in una lista
- 6. Il modo più veloce per ottenere l'accesso a Java?
- 7. modo veloce di ottenere indice della partita nella lista
- 8. Il modo più veloce per ottenere l'icona della shell
- 9. Il modo più veloce per invertire una stringa in C
- 10. Qual è il modo più veloce per ottenere un elemento dom?
- 11. Java Array Sort: modo veloce per ottenere una lista ordinata di indici di un array
- 12. Il modo più veloce per ottenere il massimo valore da una gamma esclusiva in rubino
- 13. modo più veloce o più idiomatico per rimuovere l'oggetto dalla lista di oggetti in Python
- 14. Qual è il modo più veloce per ottenere più copie di un albero in python?
- 15. Ottenere il primo elemento x da una lista
- 16. Suddividere una lista in haskell
- 17. Il modo migliore per rimuovere un elemento da una lista all'interno di una mappa in Immutable.js
- 18. qual è il modo più veloce per ottenere la mappa secondaria di una mappa
- 19. Il modo più veloce per ottenere un carattere all'interno di una stringa dato l'indice (PHP)
- 20. Ordina una lista per più attributi?
- 21. Il modo più veloce per ottenere il numero di pixel bianchi in un'immagine binaria utilizzando OpenCV
- 22. Il modo più veloce per le chiamate batch in WebGL
- 23. meccanismo per ottenere elemento dalla lista
- 24. Come ottenere il secondo elemento secondario di ogni elemento in una lista
- 25. Haskell Conversione Lista per lista di tuple
- 26. Il modo più veloce per ottenere il quadrante attuale di un angolo
- 27. Il modo più veloce per convertire stringhe in binario?
- 28. Iterator per il secondo all'ultimo elemento in una lista
- 29. Il modo più veloce per creare file in C#
- 30. Il modo più veloce per eseguire l'aggiornamento di massa
Penso che il recupero della * * ultimo elemento è efficiente difficile. Forse dovresti spiegare il contesto in modo più dettagliato, in modo da poter vedere se ci potrebbero essere altre strutture di dati che si adattino meglio alle tue esigenze. – phimuemue
ci sono poche ragioni per dubitare che Prelude.last abbia una buona implementazione. La domanda migliore, come dice phimuemue, è se, se stai usando 'last' molto, non hai bisogno di qualcosa di diverso dagli elenchi, ad es. Data.Sequence o qualcosa del genere. – applicative