返回元组列表的第一个值
我正在学习处理 F# 中的列表和元组,但出现了一个问题。我有两份清单:一份是姓名,另一份是姓名、年龄。
let namesToFind = [ "john", "andrea" ]
let namesAndAges = [ ("john", 10); ("andrea", 15) ]
我正在尝试创建一个函数,该函数将返回在给定名称ToFind 的名称AndAges 中找到的第一个年龄。只是第一个。
到目前为止,我有以下代码,它返回整个元组(“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
我尝试在返回语句中使用 fst() 但它无法编译并给出“此表达式预计具有类型 'a * 'b 但这里具有类型 ('c * 'd) 列表”
感谢您的帮助!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Collections.List
模块中有很多可以使用的函数。由于 F# 中没有break
或真正的return
语句,因此通常最好使用某些搜索函数,或编写递归循环函数。下面是一个示例:findInList
函数由Collections.List
模块中的两个函数组成。首先,我们有
List.tryFind 谓词列表
函数,它返回给定谓词函数返回true
的第一个项目。结果采用
option
类型的形式,可以采用两个值:None
和Some(x)
。它用于有时不会给出有用结果的函数。签名是:
tryFind : ('T -> bool) -> 'T 列表 -> 'T option
,其中'T
是项目类型,('T -> bool)
是谓词函数类型。在这种情况下,它将搜索
target
列表,查找第一个元素 (y
) 等于变量x
的元组外部函数。然后我们有
List.pick mapper list
函数,它将mapper
函数应用于每个列表,直到第一个结果不是None< /code>,返回。
此函数不会返回
option
值,但如果未找到项目,则会抛出异常。该函数还有一个名为List.tryPick
的option
变体。签名是:
pick : ('T -> 'U 选项) -> 'T 列表 -> 'U
,其中'T
是项目类型,'U
是结果类型,('T -> 'U 选项)
是映射函数类型。在这种情况下,它将遍历
source
列表,在target
数组中查找匹配项(通过List.tryFind
)每个,并将在第一个匹配处停止。如果您想显式地编写循环,则其外观如下:(
xs
和ys
是编写列表或项目序列的常见方法)There are lots of functions in the
Collections.List
module that can be used. Since there are nobreak
or a realreturn
statement in F#, it is often better to use some search function, or write a recursive loop-function. Here is an example:The
findInList
function is composed of two functions from theCollections.List
module.First we have the
List.tryFind predicate list
function, which returns the first item for which the given predicate function returnstrue
.The result is in the form of an
option
type, which can take two values:None
andSome(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 variablex
from the outer function.Then we have the
List.pick mapper list
function, which applies themapper
-function to each one, until the first result that is notNone
, 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 anoption
-variant of this function namedList.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 thetarget
array (viaList.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:
(
xs
andys
are common ways of writing lists or sequences of items)首先让我们看一下您的代码并注释所有类型:
语句
yield List.Filter ...
表示您正在创建列表序列:seq
。;>
语句
Seq.head
从列表序列中获取第一个元素:list<'a * 'b>
。因此整个函数返回一个
list<'a * 'b>
,这显然不是您函数的正确类型。我想你打算写这样的东西:有很多方法可以得到你想要的结果。你的代码已经完成一半了。我建议使用内置的 val Seq.find 代替手动过滤: (a' -> bool) -> seq<'a> -> 'a 方法:
或者您可以尝试使用不同的数据结构,例如
Map<'key, 'value>
:如果您想手动编写它,请尝试使用您的 seq表达:
First let's look at your code and annotate all the types:
The statement
yield List.Filter ...
means you're creating a sequence of lists:seq<list<'a * 'b>>
.The statement
Seq.head
takes the first element from your sequence of lists:list<'a * 'b>
.So the whole function returns a
list<'a * 'b>
, which is obviously not the right type for your function. I think you intended to write something like this:There are lots of ways you can get the results you want. Your code is already half way there. In place of filtering by hand, I recommend using the built in
val Seq.find : (a' -> bool) -> seq<'a> -> 'a
method:Or you can try using a different data structure like a
Map<'key, 'value>
:If you want to write it by hand, then try this with your seq expression:
就像首先使用这个(如下)。这样您就可以访问所有值。
这是来自 F# 交互式
Like fst use this(below) . This way you can access all the values.
This is from F# interactive