F# 元素列表的子集

F# 元素列表的子集,f#,F#,我需要从F#中第一次出现的元素中获取列表的子集。我使用一个简单的递归例程实现了这一点,如下所示: // Returns a subset of a list from the first occurrence of a given item // e.g. ignoreUpTo "B" ["A";"B";"C";"D"] yields ["C"; "D"] let rec ignoreUpTo item l = match l with | hd::tl -> if hd =

我需要从F#中第一次出现的元素中获取列表的子集。我使用一个简单的递归例程实现了这一点,如下所示:

// Returns a subset of a list from the first occurrence of a given item
// e.g. ignoreUpTo "B" ["A";"B";"C";"D"] yields ["C"; "D"]

let rec ignoreUpTo item l  = 
  match l with
  | hd::tl -> if hd = item then tl else ignoreUpTo item tl 
  | _ -> []

这可以满足我的需要,但我想知道是否有更好的方法使用F#语言中的现有列表函数来实现这一点。

您可以使用
List.skipWhile
来实现它。我假设您希望返回空列表,如果列表中的元素都不等于l项

let ignoreUpTo item l =
    match List.skipWhile ((<>) item) l with
    | [] -> []
    | x :: xs -> xs 
让我们忽略项目l=
match List.skipWhile(()项)l与
| [] -> []
|x::xs->xs
如果您使用的是F#4,现在有一个
列表。skipWhile
函数;在F#4之前,
skipWhile
功能仅在
seq
s上可用。所以你可以写:

let ignoreUpTo item l =
  l
  |> List.skipWhile ((<>) item)
  |> List.skip 1  // Because otherwise you'll get ["B"; "C"; "D"]

如果列表中不包含该元素,您打算返回什么;空名单?或者函数应该返回一个包装在选项中的列表吗?在我的例子中,空列表是可以的,因为这是我显式检查的。请注意,我只是编写了这些,还没有测试它们。特别是,我不知道当传递一个空列表时,
List.skip 1
会做什么。
match
建议@hvester在他的解决方案中发布可能是一件值得尝试的事情。哎呀,我无意中写了
takeWhile
而不是
skipWhile
。在我纠正错误的解决方案之前,两个投票支持我的人没有注意到。。。tsk,tsk.:-)
let ignoreUpTo item l =
  l
  |> List.toSeq
  |> Seq.skipWhile ((<>) item)
  |> Seq.skip 1  // Because otherwise you'll get ["B"; "C"; "D"]
  |> Seq.toList  // Optional, if you can get by with a seq instead of a list