返回元组列表的第一个值

tuc*_*caz 5 f# tuples list

我正在学习在 F# 中处理列表和元组,但出现了一个问题。我有两个列表:一个是名字,一个是名字,年龄。


let namesToFind = [ "john", "andrea" ]
let namesAndAges = [ ("john", 10); ("andrea", 15) ]
Run Code Online (Sandbox Code Playgroud)

我正在尝试创建一个函数,该函数将返回在给定 namesToFind 的 namesAndAges 中找到的第一个年龄。只是第一个。

到目前为止,我有以下代码返回整个元组(“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
Run Code Online (Sandbox Code Playgroud)

我尝试在返回语句中使用 fst() 但它没有编译并给我“这个表达式应该有类型 'a * 'b 但这里有类型 ('c * 'd) 列表”

谢谢你的帮助!

Mar*_*rot 3

模块中有很多功能Collections.List可以使用。由于 F# 中没有break或没有真正的return语句,因此通常最好使用一些搜索函数,或编写递归循环函数。这是一个例子:

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
Run Code Online (Sandbox Code Playgroud)

findInList函数由模块中的两个函数组成Collections.List

  • 首先我们有一个List.tryFind predicate list函数,它返回给定谓词函数返回的第一个项目true

    结果采用option类型的形式,可以采用两个值:NoneSome(x)。它用于有时不会给出有用结果的函数。

    签名为:tryFind : ('T -> bool) -> 'T list -> 'T option,其中'T是项目类型,('T -> bool)是谓词函数类型。

    在这种情况下,它将搜索列表target,查找第一个元素 ( ) 等于外部函数中的y变量的元组。x

  • 然后我们有一个List.pick mapper list函数,它将mapper- 函数应用于每个,直到None返回第一个不是 的结果。

    该函数不会返回option值,但如果未找到项目,则会抛出异常。option该函数还有一个名为 的变体List.tryPick

    签名为:pick : ('T -> 'U option) -> 'T list -> 'U,其中'T是项目类型,'U是结果类型,('T -> 'U option)是映射函数类型。

    在这种情况下,它将遍历-list,在数组中(通过)source查找每个匹配项,并在第一个匹配项处停止。targetList.tryFind


如果您想显式地编写循环,则其外观如下:

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
Run Code Online (Sandbox Code Playgroud)

xsys是编写列表或项目序列的常见方法)