如何在 F# 中对数组的切片进行就地排序

How to sort slice of an array in-place in F#

我想对数组的一部分进行排序,但以下代码无法按预期工作:

let arr = [|2; 8; 4; 1|]
Array.sortInPlace arr
printfn "%A" arr //1,2,4,8

let mutable arr2 = [|2; 8; 4; 1|]
Array.sortInPlace arr2.[1..]
printfn "%A" arr2.[1..] //8,4,1. Expected: 1,4,8
printfn "%A" arr2 //2,8,4,1. Expected: 2,1,4,8

mutable 关键字没有任何影响。

如何在 F# 中就地对数组的连续部分进行排序?

它似乎不起作用的原因是您没有将切片绑定到名称。从编译器的角度来看,sortInPlace 调用中的切片与您打印某些内容的切片不同。

像这样将切片绑定到一个名称,它将按照您的预期运行:

let arr2 = [|2; 8; 4; 1|]
let slice = arr2.[1..]
Array.sortInPlace slice
printfn "%A" slice

使用 System.Array.Sort 解决。使用 C# 数组而不是 F#,但我认为已经足够好了。

let arr = [|2; 8; 1; 4|]
System.Array.Sort(arr, 1, arr.Length-1)
printfn "%A" arr //[|2; 1; 4; 8|]

您可以使用 System.MemoryExtensions to sort Spans。 Spans 是围绕现有数据的 视图,不会创建任何副本。

open System

let ar = [|2; 8; 4; 1|]
ar.AsSpan().Slice(1).Sort() // taking span of array, slicing from 1 index and sort remaining elements
printfn "%A" ar // [|2; 1; 4; 8|]

注意:仅 net5 支持此功能