在列表中找到元素

时间:2017-11-05 14:03:20

标签: list f#

我构建了一个简单的函数,告诉我给定元素在列表中的实际位置。第一个位置是0:

let rec foo79 =
fun k l ->
    match k, l with
    | k, []         ->  failwith "What you are lookig for is not here"
    | k, (x::xs)    ->  if      x = k   then    0
                        else    1 + foo79 k xs

这很简单而且有效(即便如此,欢迎提出改进它的每一个建议!)。

x出现倍<的情况下,我使用此功能无法做到告诉我x位置 / strong>列表中的次数。 到目前为止,我的尝试甚至都没有接近解决方案。我实际发布它只是为了让你成为我追求的方法的一个例子。

let rec foo79b =
fun k l ->
    match k, l with
    | k, []         ->  failwith "What you are lookig for is not here"
    | k, (x::xs)    ->  if      x = k   &   (x::xs) then    1 + foo79b k xs
                        elif    x = k   &   []      then    0
                        else    1 + foo79b k xs

2 个答案:

答案 0 :(得分:2)

您的函数需要返回一个位置列表,因此您可以使用累加器作为结果列表。同时,您可以使用另一个辅助参数来处理索引,而不必在呼叫站点求和:

let findAllPos elem lst = 
    let rec foo79 =
        fun k l i acc ->
            match k, l with
            | k, []      -> acc
            | k, (x::xs) -> if x = k then foo79 k xs (i+1) (i::acc)
                            else          foo79 k xs (i+1)     acc
    foo79 elem lst 0 []

通过这种方式,它变得更简单,更重要的是使您的解决方案成为tail recursive。如果您不相信我尝试使用此foo79 400000 [0..400000]调用您的第一个函数,请尝试我提议的findAllPos 400000 [0..400000]

答案 1 :(得分:1)

let positions (x: 'a) (xs: 'a seq) : int seq =
    xs
    |> Seq.mapi (fun i y -> if y = x then Some i else None)
    |> Seq.choose id

// [0; 0; 2; 3; 4; 0; 6] |> positions 0;;
// val it : seq<int> = seq [0; 1; 5]

也适用于序列。

这个只适用于列表(不是序列),可能很慢:

let positions' (x: 'a) (xs: 'a list) : int list =
    [0..(Seq.length xs - 1)]
    |> List.filter (fun i -> xs.[i] = x)

// [0; 0; 2; 3; 4; 0; 6] |> positions' 0;;
// val it : int list = [0; 1; 5]