Value of the last element of a list - list

how to get the value of the last element of a List? I've noted that List.hd (or .Head) return an item, while List.tl (or .Tail) returns a List.
Is rev the List and get the hd the only way around? Thanks.

Try this function. It uses recursion, though it gets optimised to iteration anyway since it's tail recursion. In any case, it is most likely quicker than reversing the entire list (using List.rev).
let rec last = function
| hd :: [] -> hd
| hd :: tl -> last tl
| _ -> failwith "Empty list."
The answer of Pavel Minaev is definitely worth taking into account, however. Nonetheless, the algorithm you have requested may be useful in some rare cases, and is the most efficient way to go about the task.

In general, if you need to do this, you're doing something wrong. Since F# lists are single-linked, accessing the last element is costly - O(N), where N is size of list. Try to rewrite your algorithm so that you always access the first element, not the last (which is O(1)). If you cannot do so, chances are good that your choice of list for a data structure wasn't correct in the first place.

A quick & dirty way of doing it is by using List.reduce. Assuming the list is called ls,
let lastElement ls = List.reduce (fun _ i -> i) ls
As for efficiency, I agree with Pavel.

A more concise version based on Mitch's answer:
let lastItem = myList |> List.rev |> List.head
The myList list is sent to List.rev function. The result is then processed by List.head

Agreed, not so efficient to get the last element of list, or any other "enumerable" sequence. That said, this function already exists in the Seq module, Seq.last.

As a novice F# developer, I don't see what the harm is in doing the following
let mylist = [1;2;3;4;5]
let lastValue = mylist.[mylist.Length - 1]
Imperative in nature? Yes but no need for recursion.

The regular way to work with lists in F# is to use recursion. The first item in a list is the head (obviously) and the rest of the list is the tail (as oppose to the last item). So when a function recieves a list it processes the head and then recursively processes the rest of the list (the tail).
let reversedList = List.rev originalList
let tailItem = List.hd reversedList

I think you can just write
list.[0..list.Length-1]

You can call List.Head to get the first element of a list, such that the below expression evaluates to true:
let lst = [1;2;3;4;5]
List.head lst = 1
However, calling List.Tail will return every element in the list after the first element, such that the below expression is true:
let lst = [1;2;3;4;5]
List.tail lst = [2;3;4;5]
Like some other people have mentioned, there isn't an efficient way in F# to get the tail end of a list, basic lists just aren't built with that functionality in mind. If you really want to get the last element you're going to have to reverse your list first, and then take the new head (which was the previous tail).
let lst = [1;2;3;4;5]
(List.head (List.rev lst) ) = 5

Below code worked fine with me, I've an array of integers, want to start from the 5th item, then take it minus the item number
Sum of [Array(xi) - Array(xi-5)] where i start at 5
The code used is:
series |> Array.windowed 5
|> Array.fold (fun s x ->
(x |> Array.rev |> Array.head) - (x |> Array.head) + s) 0
|> float

It's a very old question, but just in case someone comes here:
with FSharp 5, you can do x.[^index] where index will start at the end of the array / list.
let a = [1;2;3;4;5;6;7;8;9]
a.[^0] is 9
a.[^1] is 8
etc

Related

Tranpose a list list in OCaml

let rec transpose list = match list with
| [] -> []
| [] :: xss -> transpose xss
| (x::xs) :: xss ->
(x :: List.map List.hd xss) :: transpose (xs :: List.map List.tl xss)
I found this code on this website and it transposes a list list or in my case a matrix from n × m to m × n.The only problem is I have no idea how it works. Can anyone please explain it step by step, line by line.
You should provide the link to the code as well, for context, or look on that question for an explanation.
Either way, I suspect other new OCaml programmers will come to this question looking for an answer.
-- After a quick Google search I believe this was the question you found the code from.
let rec transpose list = match list with
Create a function called transpose, make it recursive (rec) as we will make the function call itself. It will take an input parameter called list, where the type is determined by OCaml's type-system later.
Match the input parameter list with the following cases. That is, when the function finds a pattern matching those cases, it will execute that particular line of code. If code written does not cover all cases, OCaml will notify that not all cases are exhaustive and will cause a match_failure if it encounters cases that it doesn't cover.
First case:
| [] -> []
If we hit an empty list, return an empty list. This will end the recursion as the empty list is appended to the final result and returned. The empty list is a base case, where we meet a list with nothing inside, or it has recursed till there is nothing left. (the transpose of an empty list is ... and empty list)
| [] :: xss -> transpose xss
This is the case where there are still items in the list. Since it is a list of list, each element in the list we pass in is another list. i.e, [[1;2];[3;4]], so this function handles the case where we have [[];[1;2];[5;6]], it will skip the empty inner list, and then call transpose on the other [[1;2];[5;6]], since we don't need to transpose an empty list. Note that xss is the rest of the list (hence list of list), not just the next element only (which is just a list).
| (x::xs) :: xss ->
(x :: List.map List.hd xss) :: transpose (xs :: List.map List.tl xss)
This is the first case that will be matched when we pass in any regular list of list of length > 1, OCaml is able to match and also "unwrap" each element by breaking it down to fit the pattern, so we can immediately compute those elements without using nested match statements. In this case, we split the list of list into the (x::xs) list (first element) and the remaining list of list, xss. We could have also done it as x::xss but x will be a list that we need to break down into individual elements again.
For example, in [[1;2];[3;4]], (x::xs) will be [1;2] and xss will be [[3;4]]
(x :: List.map List.hd xss) will take the first element in the first list, in the given example, x will be 1. And apply that value to the List.hd of every item in xss list, (List.Map applies a function to every value in the list).
This is where it seems a little complicated. How you can look at it is: When you call List.hd [1;2;3] it will return 1 since it's the head. So when we do 3 :: List.map List.hd [[1;2]] it will return int list = [3; 1]. and it we did 3 :: List.map List.hd [[1;2];[4;5]] we get [3;1;4] as we are getting the head of every list inside the larger list, and appending 3 at the front of the resulting list.
If you did List.map List.tl [[1;2];[4;5]] instead your return type would be [2;5] since List.map applies the List.tl function to every list. You can use List.map to apply say a multiplication function (or anything complicated) to each item in the list in a quick and easy way.
The remaining transpose (xs :: List.map List.tl xss) just calls transpose to the remaining items in the list, which is the tail values of xss (all lists), appended with elements in xs. Try this out on paper if you feel you need a more concrete grasp on it.

Appending lists in SML

I'm trying to add an int list list with another int list list using the append function, but I can't get it to work the way I want.
Say that I want to append [[1,2,3,4,5]] with [6,7] so that I get [[1,2,3,4,5,6,7]].
Here's my attempt: [1,2,3,4,5]::[]#[6,7]::[], but it just gives me the list I want to append as a list of its own instead of the two lists combined into one, like this: [[1,2,3,4,5],[6,7]].
How can I re-write the operation to make it return [[1,2,3,4,5,6,7]]?
Your question is too unspecific. You are dealing with nested lists. Do you want to append the second list to every inner list of the nested list, or only the first one? Your example doesn't tell.
For the former:
fun appendAll xss ys = List.map (fn xs => xs # ys) xss
For the latter:
fun appendHd [] ys = raise Empty
| appendHd (xs::xss) ys = (xs # ys)::xss
However, both of these should rarely be needed, and I somehow feel that you are trying to solve the wrong problem if you end up there.

OCaml Error involving lists

I'm still fairly new to OCaml, and would like some assistance on optimizing code.
I'm trying to multiply each element of a given list by the list's last element.
Here's a snippet of my code:
(* Find the last element of a function *)
let rec lastE = function
| [] -> []
| [x] -> x
| _ :: t -> lastE t;;
(*multiply a list by the last element*)
let rec lmul list =
match list with
[] -> []
| hd::tl -> (hd *. (lastE tl)) :: lmul tl;;
When I run the code I get this error message:
Error: This expression has type float list but
an expression was expected of type 'a list list
I'm been studying it for a while, but any assistance on this problem will be much appreciated.
To rephrase differently what Dave Newman is telling you, your basic problem is that lastE needs to handle an empty list differently. If lastE is supposed to return a number, it has to return a number in all cases. As it stands, lastE returns a list when it receives an empty list.
If you don't want to use List.map (again as Dave Newman suggests), you might at least consider calling lastE just once rather than once for each element of the list. This will make a big difference for long lists.

Ocaml manipulating lists

real basic question here: I'm new to Ocaml and I'm having issues trying to manipulate lists. I've read http://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html, and I'm unfortunately still confused....I'm new to functional programming.
If I have, say, the following function:
let stoverfl list1 list2 list3 =
match list1 with
|[]->None
|h::list1 -> (*what I want to do goes in here*)
I want to take a look at the first elements of list2 and list3, compare them, and if they're equal, add the first element of list3 to list2, else don't modify the lists. I don't really care about error checking now (i.e. checking to see if the list has at least one element, etc.).
My attempt:
h::list1 -> let cmp1 = hd list2 (*this should return the first elemnt of list2??*)
let cmp2 = hd list3
if(cmp1=cmp2) then
let updlist2 = concat list2 hd list3
let updlist3 = hd list3
(*pass updlist2 and updlist3 instead of list2 and list3 to next function*)
else
(*do nothing; pass list2 and list3 as normal*)
I feel like I'm doing it all wrong...any advice would be appreciated!
Thanks.
You say you want to add the first element of list3 to list2. When a functional programmer says something like this what it means is that they want to construct a new list as described. You can't actually modify list2--lists are immutable and names are permanently bound to a single value. In fact, it seems like you want to construct two new lists. One of them has the first element of list2 at the front of list3. The other one is the remainder of list2 (all but the first element).
Assuming this is what you mean, and assuming you're not worried whether the lists are empty, then here's one way to get these values:
let updlist2 = List.tl list2 in
let updlist3 = (List.hd list2) :: list3
It's actually pretty close to what you wrote.
However, I wonder what you're going to do with these values next. If you want to pass them along to another function, it would be more normal to have the lets outside the if. As an example, here's some code that calls a function g with either a list, or the tail of the list, depending on the first element of the list:
let arg_for_g =
match the_list with
| [] -> [] (* No tail of the list *)
| head :: tail -> if head = 3 then tail else the_list
in
g arg_for_g
If you put the lets inside the if, you'll need to code two different calls to your next function. That could be fine, it depends on exactly what you're going to do with your values.
(As a side note, you should worry about whether the lists are empty! If you use a match statement you can detect that case pretty easily.)

I want to do 2 things after a "then" statement in a "if.. then.. else" statement

let rec filtersList2fromList1 (List1:string list) (List2:string list) : string list =
let finalList = [] in
match List1 with
| s :: tl -> if List.mem s List2 = true
then finalList # [s] else filtersList2fromList1 tl List2
| [] -> []
so that,
filtersList2fromList1 ["x";"y";"z"] ["z";"x"] would be ["x";"z"]
filtersList2fromList1 ["x";"y";"z"] ["x"] would be ["x"]
what I would like to add is, if the "if" statement is true, not only it would execute "finalList # [s]", but also "filtersList2fromList1 tl List2" so that it will be a recursion. Without executing "filtersList2fromList1 tl List2" when it is true,
filtersList2fromList1 ["x";"y";"z"] ["z";"x"] would only be ["x"], which is wrong.
How should I solve this problem?
Thank you very much
To answer your specific question, you'd either use a semi-colon or a let...in construct. In your case, neither will do what you want however.
You should read through the documentation on the standard library, as the List module contains everything you need to do what you want:
let filterList2fromList1 list1 list2 =
List.filter (fun x -> List.mem x list2) list1
Note that since you mentioned recursion, I'm assuming that when you wrote dolls_of you meant filtersList2fromList1. Also I'm assuming that List1 and List2 are supposed to be list1 and list2, since the former would be an error.
It should also be pointed out that # is an O(n) operation and it is not recommended to use it to build up lists. However as Niki pointed out in the comments, your use of finalList is pointless, so you don't actually need # anyway.
To answer your question: You can execute two expressions after another by separating them with a ;. However dolls_of is a function without side effects, so executing it without doing anything with its result would make little sense.
What you actually want to do, as far as I can tell, is:
if List.mem s list2
then s :: filtersList2fromList1 tl list2
else filtersList2fromList1 tl list2