Reputation:
This is what my initial thought was and there were no issues until it was called; What is wrong with this exactly?
let SecLastItem myList=
List.rev myList
|>printfn myList.[1]
How do I rectify the problem here? What is the best way to find the 2nd to last item of a list?
Upvotes: 1
Views: 711
Reputation: 1749
What is the best way to find the 2nd to last item of a list?
If you do not want to reverse the list, you can use pattern matching and return an option if the list is not long enough for a 'second to last item'. Something like this.
let rec secondToLast ls =
match ls with
| [] -> None
| h :: ht :: [] -> Some(h)
| h :: t -> secondToLast t
test with
printfn "%A" (secondToLast [1; 2; 3; 4])
Upvotes: 5
Reputation: 5049
printfn
expects a format first printfn "%A" arg
But there is more, functional programming favors immutability so List.rev
returns a new list without modifying mylist
So printing the second item in myList won't give the second to last just the second from start (if it exists otherwise it'll crash)
That said you should separate function doing something and logging/printing that' better for reuse and composability.
// trySecLastItem : 'a list -> 'a option
let trySecLastItem = List.rev >> List.tryItem 2
// usage
printfn "%d" (trySecLastItem someList) // ex Some 42 or None
Now as trySecLastItem
returns an option you have to take care of that (using defaultArg
for example)
// maybeSecLast : int option
let maybeSecLast = trySecLastItem someList
printfn "%d" (defaultArg maybeSecLast 42)
Upvotes: 5
Reputation: 6537
You need to have a formatter with printfn
let SecLastItem myList=
let revList = List.rev myList
printfn "%A" revList.[1]
Upvotes: 3