Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning first value of list of tuples

Tags:

list

tuples

f#

I'm learning to deal with Lists and Tuples in F# and a problem came up. I have two lists: one of names and one with names,ages.


let namesToFind = [ "john", "andrea" ]
let namesAndAges = [ ("john", 10); ("andrea", 15) ]

I'm trying to create a function that will return the first age found in namesAndAges given namesToFind. Just the first.

So far I have the following code which returns the entire tuple ("john", 10).


let findInList source target = 
            let itemFound = seq { for n in source do
                                    yield target |> List.filter (fun (x,y) -> x = n)  }                                
                                |> Seq.head    
            itemFound

I tried using fst() in the returning statement but it does not compile and gives me "This expression was expected to have type 'a * 'b but here has type ('c * 'd) list"

Thanks for any help!

like image 717
tucaz Avatar asked Dec 22 '10 20:12

tucaz


People also ask

How do you get the first element of a tuple in a list?

To get the first element of each tuple in a list: Declare a new variable and set it to an empty list. Use a for loop to iterate over the list of tuples. On each iteration, append the first tuple element to the new list.

How do you return a tuple list?

That's because you can return a tuple by separating each item with a comma, as shown in the above example. “It is actually the comma which makes a tuple, not the parentheses,” the documentation points out. However, parentheses are required with empty tuples or to avoid confusion.

How do I get the first element of a list?

Approach #2 : Using zip and unpacking(*) operator This method uses zip with * or unpacking operator which passes all the items inside the 'lst' as arguments to zip function. Thus, all the first element will become the first tuple of the zipped list. Returning the 0th element will thus, solve the purpose.

How do you get the first value in a list Python?

To access the first element (12) of a list, we can use the subscript syntax [ ] by passing an index 0 . In Python lists are zero-indexed, so the first element is available at index 0 . Similarly, we can also use the slicing syntax [:1] to get the first element of a list in Python.


1 Answers

There are lots of functions in the Collections.List module that can be used. Since there are no break or a real return statement in F#, it is often better to use some search function, or write a recursive loop-function. Here is an example:

let namesToFind = [ "john"; "andrea" ]
let namesAndAges = [ "john", 10; "andrea", 15 ]

let findInList source target =
  List.pick (fun x -> List.tryFind (fun (y,_) -> x = y) target) source

findInList namesToFind namesAndAges

The findInList function is composed of two functions from the Collections.List module.

  • First we have the List.tryFind predicate list function, which returns the first item for which the given predicate function returns true.

    The result is in the form of an option type, which can take two values: None and Some(x). It is used for functions that sometimes give no useful result.

    The signature is: tryFind : ('T -> bool) -> 'T list -> 'T option, where 'T is the item type, and ('T -> bool) is the predicate function type.

    In this case it will search trough the target list, looking for tuples where the first element (y) equals the variable x from the outer function.

  • Then we have the List.pick mapper list function, which applies the mapper-function to each one, until the first result that is not None, which is returned.

    This function will not return an option value, but will instead throw an exception if no item is found. There is also an option-variant of this function named List.tryPick.

    The signature is: pick : ('T -> 'U option) -> 'T list -> 'U, where 'T is the item type, 'U is the result type, and ('T -> 'U option) is the mapping function type.

    In this case it will go through the source-list, looking for matches in the target array (via List.tryFind) for each one, and will stop at the first match.


If you want to write the loops explicitly, here is how it could look:

let findInList source target =
  let rec loop names =
    match names with
    | (name1::xs) -> // Look at the current item in the
                     // source list, and see if there are
                     // any matches in the target list.
        let rec loop2 tuples =
          match tuples with
          | ((name2,age)::ys) ->  // Look at the current tuple in
                                  // the target list, and see if
                                  // it matches the current item.
              if name1 = name2 then
                Some (name2, age) // Found a  match!
              else
                loop2 ys          // Nothing yet; Continue looking.
          | [] -> None            // No more items, return "nothing"
        match loop2 target with           // Start the loop
        | Some (name, age) -> (name, age) // Found a match!
        | None -> loop rest               // Nothing yet; Continue looking.
    | [] -> failwith "No name found" // No more items.

  // Start the loop
  loop source

(xs and ys are common ways of writing lists or sequences of items)

like image 126
Markus Jarderot Avatar answered Sep 27 '22 17:09

Markus Jarderot