在F#中移动数组

时间:2019-03-13 03:52:57

标签: arrays f#

因此,我有一个函数,可以将数组中的一些三进制值按所需的量进行移位,但是当我对任何数组进行移位时,(b)个值(如果向左移位,则在右侧,如果向右移位,则在左侧)将始终替换为null。这是我的代码:

let ( <<| ) (a:FalseTrit[]) (b:int) =
    array.Copy(a, b, a, 0, a.Length - 1)
    array.Clear(a, a.Length - b, b)
let ( |>> ) (a:FalseTrit[]) (b:int) =
    array.Copy(a, 0, a, b, a.Length - b)
    array.Clear(a, 0, b)

我在互联网上找不到任何答案。有没有更好的方法可以执行此操作,或者我做错了什么?预先感谢。

2 个答案:

答案 0 :(得分:1)

Array.Clear将数组中的元素范围设置为每种元素类型的 default 值(请参见docs)。

由于FalseTrit是引用类型而非值类型,因此它具有默认值null

答案 1 :(得分:0)

通过Alexey Romanov扩展注释,为什么您比Microsoft.FSharp.Collections.Array的实例成员更喜欢System.Array模块中的标准库函数:类型推断使它们更易于使用,并且使参数更美观。 / p>

虽然Array.blit的文档在数组重叠方面没有保证System.Array.Copy,但是我强烈怀疑由于其底层实现,因此同样适用:

  

如果 sourceArray destinationArray 重叠,则此方法的行为就像    sourceArray 的原始值保存在一个临时文件中    destinationArray 之前的位置。

let (<<|) a b =
    Array.blit a b a 0 (Array.length a - b)
    Array.fill a (Array.length a - b) b Unchecked.defaultof<_>
// val ( <<| ) : a:'a [] -> b:int -> unit
let (|>>) a b =
    Array.blit a 0 a b (Array.length a - b)
    Array.fill a 0 b Unchecked.defaultof<_>
// val ( |>> ) : a:'a [] -> b:int -> unit 

此处,原始代码的行为得以保留:Unchecked.defaultof将为引用类型返回null

从风格上讲,考虑将代码替换为返回新数组的生成器表达式,因为不认为变异是功能上的最佳实践,自定义运算符也不返回unit

let (<<|) a b = [|
    for i in b..Array.length a - 1 + b ->
        if i < Array.length a then a.[i]
        else Unchecked.defaultof<_> |]
// val ( <<| ) : a:'a [] -> b:int -> 'a []
let (|>>) a b = [|
    for i in -b..Array.length a - 1 - b ->
        if i < 0 then Unchecked.defaultof<_>
        else a.[i] |]
// val ( |>> ) : a:'a [] -> b:int -> 'a []