Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
List 返回元组列表的第一个值_List_F#_Tuples - Fatal编程技术网

List 返回元组列表的第一个值

List 返回元组列表的第一个值,list,f#,tuples,List,F#,Tuples,我正在学习处理F#中的列表和元组,出现了一个问题。我有两个清单:一个是名字,另一个是名字,年龄 let namesToFind = [ "john", "andrea" ] let namesAndAges = [ ("john", 10); ("andrea", 15) ] 我正在尝试创建一个函数,该函数将返回给定namesToFind的namesAndAges中找到的第一个age。只是第一次 到目前为止,我有以下返回整个元组的代码(“john”,10) 我尝试在返回语句中使用fst(),

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


let namesToFind = [ "john", "andrea" ]
let namesAndAges = [ ("john", 10); ("andrea", 15) ]
我正在尝试创建一个函数,该函数将返回给定namesToFind的namesAndAges中找到的第一个age。只是第一次

到目前为止,我有以下返回整个元组的代码(“john”,10)

我尝试在返回语句中使用fst(),但它没有编译,并给出“此表达式的类型应为'a*'b,但此处的类型为('c*'d)list”


谢谢你的帮助

首先,让我们看一下您的代码并注释所有类型:

let findInList source target = 
    let itemFound =
        seq {
            for n in source do
                yield target |> List.filter (fun (x,y) -> x = n) }                                
        |> Seq.head    
    itemFound
语句
yield List.Filter…
表示您正在创建一系列列表:
seq

语句
Seq.head
从列表序列中获取第一个元素:
list

因此,整个函数返回一个
列表
,这显然不是函数的正确类型。我想你打算写这样的东西:

let findInList source target = 
    let itemFound =
        target                               // list<'a * 'b>
        |> List.filter (fun (x,y) -> x = n)  // list<'a * 'b>
        |> Seq.head                          // 'a * 'b
    itemFound                                // function returns 'a * 'b
或者,您可以尝试使用不同的数据结构,如
地图


集合.List
模块中有许多可以使用的函数。由于F#中没有
break
或real
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
findInList
函数由
Collections.List
模块中的两个函数组成

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

    结果以
    选项
    类型的形式出现,该类型可以有两个值:
    None
    Some(x)
    。它用于有时不会给出有用结果的函数

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

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

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

    此函数不会返回
    选项
    值,但如果未找到任何项,则会引发异常。此函数还有一个名为
    List.tryPick的
    选项
    -变体

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

    在这种情况下,它将遍历
    -列表,在
    目标
    数组中(通过
    list.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
xs
ys
是编写项目列表或序列的常用方法)

像fst一样使用此选项(如下)。这样您就可以访问所有值

这是F#interactive的

let a = ((1,2), (3,4));
let b = snd (fst a);;

//interactive output below.
val a : (int * int) * (int * int) = ((1, 2), (3, 4))
val b : int = 2
let findInList source target = 
    seq {
        for (x, y) in source do
            if x = target then
                yield y}
    |> Seq.head
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
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
let a = ((1,2), (3,4));
let b = snd (fst a);;

//interactive output below.
val a : (int * int) * (int * int) = ((1, 2), (3, 4))
val b : int = 2