2016-02-02 114 views
3

我需要從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#語言的現有列表功能。

+0

什麼是你的,如果列表返回計劃不包含元素;一個空的列表?或者該函數應該返回一個包含在選項中的列表? –

+0

在我的情況下,空列表是好的,因爲這是我明確檢查。 – Russell

回答

4

如果您使用F#4,現在有一個List.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"] 

如果您使用F#3.1或更早版本,你需要把你的名單分成一個seq第一:

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 
+0

請注意,我只寫了這些,還沒有測試過它們。特別是,我不知道什麼'List.skip 1'在傳遞一個空列表時會做什麼。 @hvester在他的解決方案中發佈的'匹配'建議可能是一件好事。 – rmunn

+0

糟糕,我偶然寫了'takeWhile'而不是'skipWhile'。在糾正錯誤之前,我提出了不正確的解決方案的兩個人沒有注意到...... tsk,tsk。 :-) – rmunn

3

您可以使用List.skipWhile來實現它。我假設你想要返回空列表,如果列表中沒有任何元素等於item。

let ignoreUpTo item l = 
    match List.skipWhile ((<>) item) l with 
    | [] -> [] 
    | x :: xs -> xs