简体   繁体   English

空表头

[英]Head of empty list

I'm trying to make a function which returns a list of the first element of each sub-list, including empty lists being returned as [].我正在尝试创建一个函数,该函数返回每个子列表的第一个元素的列表,包括作为 [] 返回的空列表。

let firstCol (lst: 'a list list) =
  List.map List.head lst

This works as long as there are no empty lists, but I get the following error message when my input includes an empty list:只要没有空列表,这就会起作用,但是当我的输入包含空列表时,我收到以下错误消息:

System.ArgumentException: The input list was empty.

How do I go about this?我该怎么做? Thanks in advance.提前致谢。

You can use List.tryHead or write your own function from the ground, or with helpers like List.fold / List.foldBack .您可以使用List.tryHeadList.tryHead编写自己的函数,或者使用List.fold / List.foldBack类的List.fold List.foldBack

If you do List.tryHead you get an option as a result, either Some element, or None if the list is empty.如果你执行List.tryHead你会得到一个选项,要么是Some element,要么None如果列表是空的。 So you must think what happens in the None case.所以你必须考虑在None情况下会发生什么。 You cannot return an empty list for a sub-list, because a list must have the same type.您不能为子列表返回空列表,因为列表必须具有相同的类型。 But you could for example skip empty lists.但是您可以例如跳过空列表。 Or just keep the Option.或者只是保留选项。 As it indicates when a list was empty.因为它表明列表何时为空。

let xs = [[1;2;3];[];[4;5;6];[];[7;8;9]]

printfn "%A" (List.map List.tryHead xs)

returning回来

[Some 1; None; Some 4; None; Some 7]

You could skip the empty sub-lists你可以跳过空的子列表

printfn "%A" (List.choose List.tryHead xs)

so you get所以你得到

[1;4;7]

or do it on your own, with List.foldBack或者自己做,使用List.foldBack

let firstCol xs = 
    let folder xs acc =
        match List.tryHead xs with
        | Some x -> x :: acc
        | None   -> acc
    List.foldBack folder xs []

Or even more basic或者更基本的

let rec firstCol xs =
    match xs with
    | []           -> []
    | []::xss      -> firstCol xss
    | (x::xs)::xss -> x :: firstCol (xss)

The last version is not tail-recursive, but anyway, you should try and train to understand such a recursive definition.最后一个版本不是尾递归的,但无论如何,您应该尝试和训练以理解这样的递归定义。 And be able to turn such a function into an tail-recursive on your own.并且能够自己将这样的函数变成尾递归。

What you're asking for can't be done with the signature you currently have.使用您当前拥有的签名无法完成您的要求。 Consider this input:考虑这个输入:

[
    [1; 2]
    []
    [3; 4]
]

It looks like you're asking for the following output:看起来您要求以下输出:

[
    1
    []
    3
]

However, that isn't a legal list in F# because its elements don't have the same type.但是,这不是 F# 中的合法列表,因为它的元素没有相同的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM