获取F#集合中两个元素之间的元素

获取F#集合中两个元素之间的元素,f#,F#,我想获取一个列表或数组,并给定集合中的两个元素,获取它们之间的所有元素。但是我想以循环的方式来做这件事,这样给定一个列表[1;2;3;4;5;6],如果我要求4到2之间的元素,我会得到[5;6;1] 由于习惯了命令式编程,我可以很容易地用循环实现这一点,但我认为在F#中可能有一种更好的惯用方法 编辑 在找到Array.indexed函数后,我提出了一种方法 let elementsBetween (first:int) (second:int) (elements: array<'T>

我想获取一个列表或数组,并给定集合中的两个元素,获取它们之间的所有元素。但是我想以循环的方式来做这件事,这样给定一个列表
[1;2;3;4;5;6]
,如果我要求4到2之间的元素,我会得到
[5;6;1]

由于习惯了命令式编程,我可以很容易地用循环实现这一点,但我认为在F#中可能有一种更好的惯用方法

编辑

在找到Array.indexed函数后,我提出了一种方法

let elementsBetween (first:int) (second:int) (elements: array<'T>) =
    let diff = second - first
    elements 
    |> Array.indexed
    |> Array.filter (fun (index,element) -> if diff = 0 then false
                                            else if diff > 0 then index > first && index < second
                                            else if diff < 0 then index > first || index < second
                                            else false

让elementsBetween(first:int)(second:int)(elements:array我的普通计算机上没有f#编译器,所以我还没有测试过它。它应该是这样的

[编辑]谢谢@FoggyFinder给我看。我现在已经用它测试了下面的代码

[编辑]这应该可以在单个过程中找到圆形范围

let x = [1;2;3;4;5]
let findCircRange l first second =
    let rec findUpTo (l':int list) f (s:int) : (int list * int list) = 
        match l' with 
        | i::tail -> 
            if i = s then tail, (f [])
            else findUpTo tail (fun acc -> f (i::acc)) s
        // In case we are passed an empty list.
        | _ -> [], (f [])
    let remainder, upToStart = findUpTo l id first
    // concatenate the list after start with the list before start. 
    let newBuffer = remainder@upToStart
    snd <| findUpTo newBuffer id second

let values = findCircRange x 4 2
printf "%A" values
设x=[1;2;3;4;5]
让FindCircl先搜索=
让rec findUpTo(l):int list)f(s:int):(int list*int list)=
配上
|i::tail->
如果i=s,则为尾部(f[])
else findUpTo tail(fun acc->f(i::acc))s
//万一我们收到一张空名单。
|(f[])
让余数,uptstart=findUpTo l id优先
//将启动后列表与启动前列表连接起来。
让newBuffer=remainder@upToStart

snd我的普通计算机上没有f#编译器,所以我还没有测试它。它应该是这样的

[编辑]谢谢@FoggyFinder给我看。我现在已经用它测试了下面的代码

[编辑]这应该可以在单个过程中找到圆形范围

let x = [1;2;3;4;5]
let findCircRange l first second =
    let rec findUpTo (l':int list) f (s:int) : (int list * int list) = 
        match l' with 
        | i::tail -> 
            if i = s then tail, (f [])
            else findUpTo tail (fun acc -> f (i::acc)) s
        // In case we are passed an empty list.
        | _ -> [], (f [])
    let remainder, upToStart = findUpTo l id first
    // concatenate the list after start with the list before start. 
    let newBuffer = remainder@upToStart
    snd <| findUpTo newBuffer id second

let values = findCircRange x 4 2
printf "%A" values
设x=[1;2;3;4;5]
让FindCircl先搜索=
让rec findUpTo(l):int list)f(s:int):(int list*int list)=
配上
|i::tail->
如果i=s,则为尾部(f[])
else findUpTo tail(fun acc->f(i::acc))s
//万一我们收到一张空名单。
|(f[])
让余数,uptstart=findUpTo l id优先
//将启动后列表与启动前列表连接起来。
让newBuffer=remainder@upToStart

snd您应该看看MSDN,Collections.Seq模块

让我们试着聪明一点:

let elementsBetween a e1 e2 =
    let aa = a |> Seq.append a
    let i1 = aa |> Seq.findIndex (fun e -> e = e1)
    let i2 = aa |> Seq.skip i1 |> Seq.findIndex (fun e -> e = e2)
    aa |> Seq.skip(i1+1) |> Seq.take(i2-1)

您应该看看MSDN,例如Collections.Seq模块

让我们试着聪明一点:

let elementsBetween a e1 e2 =
    let aa = a |> Seq.append a
    let i1 = aa |> Seq.findIndex (fun e -> e = e1)
    let i2 = aa |> Seq.skip i1 |> Seq.findIndex (fun e -> e = e2)
    aa |> Seq.skip(i1+1) |> Seq.take(i2-1)

下面是一个变体,它使用了您的diff思想和列表和列表切片
(l.Length*2)然后
failwith“first不能大于列表长度乘以2”
如果秒>(l.Length*2),则
failwith“秒不能大于列表长度乘以2”
设diff=second-first
匹配差异
| 0 -> []
|_uu当差异>0&(abs差异)l.[第一个+1)…(第二个-1)]
|_uu当差异>0->(l@l)[第一次+1)…(第二次-1)]
|_uu当差异<0&(abs diff)l.[第二+1)…(第二+第一-1)]
|_uu当差异<0->(l@l)[(第二+1)…(第二+1-1)]

下面是一个变体,它使用了您的diff思想,使用列表和列表切片
(l.Length*2)然后
failwith“first不能大于列表长度乘以2”
如果秒>(l.Length*2),则
failwith“秒不能大于列表长度乘以2”
设diff=second-first
匹配差异
| 0 -> []
|_uu当差异>0&(abs差异)l.[第一个+1)…(第二个-1)]
|_uu当差异>0->(l@l)[第一次+1)…(第二次-1)]
|_uu当差异<0&(abs diff)l.[第二+1)…(第二+第一-1)]
|_uu当差异<0->(l@l)[(第二+1)…(第二+1-1)]


您需要提供您的尝试。虽然我们大多数人都可以轻松回答这一问题,但您需要展示您的努力。因此,我对此投了反对票。如果出现重复的情况,会发生什么?如果没有找到一个限值,该怎么办?感谢您展示了您的尝试。我反转了我的反对票。重复的票是可以的。如果没有找到限值,应该b这是一个错误。我不需要精确的代码,只需要一些通用的方法。这种方法的一种变体是使用列表切片,例如…[(第一+1)…(第二-1)]。您需要提供您的尝试。虽然我们大多数人都可以轻松回答这一问题,但您需要展示您的努力。因此,我对此投了反对票。如果出现重复的情况,会发生什么?如果没有找到一个限值,该怎么办?感谢您展示了您的尝试。我反转了我的反对票。没有找到重复的限值应该是e错误。我不需要精确的代码,只需要一些通用的方法。这种方法的一种变体是使用列表切片,例如…[(第一+1)…(第二-1)]。谢谢,看到列表和数组的方法很好。@FoggyFinder谢谢。我通常使用www.tryfsharp.com,但它需要一个我在那台计算机上没有的安装。谢谢,看到列表和数组的方法很好。@FoggyFinder谢谢。我通常使用www.tryfsharp.com,但它需要一个我曾经安装过的安装在那台计算机上没有。看起来只有当
first
既是第一个元素的索引又是第一个元素的值时,它才会起作用。也许我误解了,但我认为
[1;2;3;4;5;6]
只是一个例子。我不认为这适用于像
[11;13;14;16]这样的任意缓冲区
。这需要列表以0开头
[0;1;2;3;4;5;6]
@Phillips Cottgivens我没有检查代码是否准确,因为注释中的OP
我不需要精确的代码,这只是一些一般的方法。
。因为答案是CC,请随意编辑答案。这看起来只有当
first
同时是第一个元素的索引和值时才有效。P呃,我误解了,但我认为
[1;2;3;4;5;6]
只是一个例子。我不认为这是