List 返回元组列表的第一个值
我正在学习处理F#中的列表和元组,出现了一个问题。我有两个清单:一个是名字,另一个是名字,年龄List 返回元组列表的第一个值,list,f#,tuples,List,F#,Tuples,我正在学习处理F#中的列表和元组,出现了一个问题。我有两个清单:一个是名字,另一个是名字,年龄 let namesToFind = [ "john", "andrea" ] let namesAndAges = [ ("john", 10); ("andrea", 15) ] 我正在尝试创建一个函数,该函数将返回给定namesToFind的namesAndAges中找到的第一个age。只是第一次 到目前为止,我有以下返回整个元组的代码(“john”,10) 我尝试在返回语句中使用fst(),
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
或realreturn
语句,因此通常最好使用一些搜索函数,或编写递归循环函数。以下是一个例子:
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