Смещение массивов в F # - PullRequest
0 голосов
/ 13 марта 2019

Итак, у меня есть функция, которая сдвигает некоторые троичные значения в массиве на требуемую величину, но когда я сдвигаю любой массив, (b) значения (я) (справа, если смещается влево, и слева, если смещается вправо)всегда будет заменено на ноль.Вот мой код:

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 ]

1 голос
/ 13 марта 2019

Array.Clear устанавливает диапазон элементов в массиве равным значению по умолчанию каждого типа элемента (см. документы ).

Поскольку FalseTrit является ссылочным типом, а не типом значения, он имеет значение по умолчанию null.

0 голосов
/ 18 марта 2019

Расширение комментария Алексей Романов , почему вы предпочитаете стандартные библиотечные функции из модуля Microsoft.FSharp.Collections.Array над членами экземпляра System.Array: вывод типа облегчает их использование, а аргументы с каррированием выглядят красивее.

Хотя в документации для 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 []
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...