简体   繁体   English

从列表中输出除前 n 个元素之外的元素

[英]Outputting elements from the list except first n elements

How do you write a F# recursive function that accepts a positive integer n and a list xs as input, and returns a list except first n elements in xs ?你如何写一个 F# 递归 function 接受一个正的xs n和一个列表xs作为输入,并返回一个列表,除了前n元素?

let rec something n xs = .. something 7 [1..10] = [8; 9; 10]

I don't think that recursion is the most efficient way to solve this problem, but you can do it like this:我不认为递归是解决这个问题的最有效方法,但你可以这样做:

let rec something n xs = 
    if n > List.length xs || n < 0 then failwith "incorrect parameter n - out of range"
    else if n = 0 then xs
    else something (n-1) (xs |> List.tail)

let res = something 7 [1..10]

open System
Console.WriteLine(res)
//something 7 [1..10] = [8; 9; 10]

The simple answer is to use List.skip ... ie [0..10] |> List.skip 5简单的答案是使用List.skip ... 即[0..10] |> List.skip 5

To reimplement List.skip you'd be looking at something like:要重新实现List.skip你会看到类似的东西:

let rec listSkip n list =
    match (n, list) with
    | 0, list                 -> list
    | _, []                   -> failwith "The index is outside the legal range"
    | n, _ when n < 0         -> failwith "The index cannot be negative"
    | n, _ :: tl              -> listSkip (n - 1) tl 

As this is recursion is eligible for tail-call optimization, performance should be similar to an explicit loop.由于这是递归符合尾调用优化的条件,因此性能应该类似于显式循环。

I've avoided an explicit guard checking List.length against n because List.length requires iteration of the entire list ( which we'd have to check each round of the recursion ).我避免了针对n的显式保护检查List.length因为List.length需要整个列表的迭代(我们必须检查每一轮递归)。 Thus it's cheaper just to try and remove n items and fail if we run into an empty list before n reaches 0 .因此,如果我们在n达到0之前遇到一个空列表,尝试删除n项并失败会更便宜。

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

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