访问一个列表中的第一个元素 [F#]

7

我目前对F#很感兴趣,因为它与我以前使用的任何东西都不同。 我需要访问包含在大型列表中的每个列表的第一个元素。 如果我假设主列表包含'x'个列表,这些列表本身包含5个元素,那么访问每个第一个元素的最简单方法是什么。

let listOfLists = [[1; 2; 3; 4; 5]; [6; 7; 8; 9; 10]; [11; 12; 13; 14; 15]]

我的期望输出将是包含[1; 6; 11]的新列表。

我目前所拥有的:

let rec firstElements list  =
    match list with
    | list[head::tail] -> 
        match head with
        | [head::tail] -> 1st @ head then firstElements tail

进一步扩展这个问题,我如何获取所有第二个元素?是创建新列表而不包含第一个元素(通过类似的函数去除它们),然后重新使用相同的函数最好吗?

2个回答

5
你可以使用map来提取每个子列表的头元素:
let firstElements li =
  match li with [] -> None | h::_ -> Some h

let myfirstElements = List.map firstElements listOfLists

我正在使用Ocaml的语言,对F#了解不多,因此这可能不太准确,但是思想是一样的。
编辑:您还可以使用List.head,这会使代码更加简洁,并返回一个int列表而不是int选项列表。但是,如果你遇到一个空列表,它会抛出异常。在大多数情况下,我会避免在这种情况下使用List.head或List.tail。

2
这将返回一个 int option 列表,而不是 int 列表。 - Taylor Wood
1
无论如何,我认为这样做更好,因为它强制你处理空列表的情况,而不是从List.head获得错误。 - Pandemonium
1
谢谢您的回答。关于这个问题,我有一个快速的问题,如果列表长度未知,您将如何应用它?比如说,我想提取所有第二个元素。我需要先编写一个函数来删除第一个元素,然后重新应用此函数吗?然后我可以继续这样做,直到所有元素都被提取并分别放在不同的列表中? - Code Guy
3
除了 List.head 外,还有一个名为 List.tryHead 的函数,它与本答案中的 firstElements 函数完全相同。在 F# 中,通常情况下,任何有可能失败的函数(例如 List.head 在空列表上会失败)都会有一个具有 try 前缀的版本,该版本返回一个选项(Option)。因此,List.head 返回一个 int 类型的值但可能会抛出异常;List.tryHead 返回一个 int option 类型的值,并且永远不会抛出异常。如果您知道您的列表永远不会为空,则使用 List.head 更容易。如果它们可能为空,则使用 List.tryHead 让您需要处理这两种情况。 - rmunn
1
@CodeGuy 在使用递归之前,看看是否可以通过模式匹配来实现。对于第二个元素,您可以使用“_ :: m :: _”情况进行匹配,然后您将获得“Some m”或“None”。 - Pandemonium
只需使用collect返回int列表。 - ca9163d9

5

访问列表中的第一个元素最简单的方法是使用List.head。由于您有一个列表的列表,所以只需要将此函数应用于List.map

let listOfLists = [ [1;2;3;4;5]; [6;7;8;9;10]; [11;12;13;14;15] ]

listOfLists 
|> List.map List.head
//val it : int list = [1; 6; 11]

现在,如果您需要访问其他元素,可以使用 List.item 或者直接使用索引 xs.[1]。但请注意,对于大型列表来说,这种方法效率较低,如果您想要快速查找,请使用数组。
listOfLists
|> List.map (List.item 1)
//val it : int list = [2; 7; 12]

使用索引:

listOfLists
|> List.map (fun x -> x.[1])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接