С массивом let foo = [|1;2;3;4|]
Я могу использовать любое из следующих для возврата части из массива.
foo.[..2]
foo.[1..2]
foo.[2..]
Как я могу сделать то же самое для Списка let foo2 = [1;2;3;4]
? Когда я пробую тот же синтаксис как массив, я добираюсь error FS00039: The field, constructor or member 'GetSlice' is not defined.
Что предпочтительный метод получения является подразделом Списка и почему они не созданы для поддержки GetSlice?
Какой предпочитаемый способ получения подраздел Списка, а почему бы и нет. Собраны для поддержки GetSlice?
Давайте сделаем последний вопрос первым и первый вопрос последним:
Почему списки не поддерживают GetSlice
Списки реализованы как связанные списки, поэтому у нас нет эффективного индексированного доступа к ним. Сравнительно говоря, foo.[|m...n|]
занимает O(n-m)
время для массивов, эквивалентный синтаксис занимает O(n)
время для списков. Это довольно большое дело, потому что в подавляющем большинстве случаев, когда это было бы полезно, он не позволяет нам эффективно использовать синтаксис нарезки.
Например, мы можем разрезать массив на части одинакового размера в линейном времени:
let foo = [|1 .. 100|]
let size = 4
let fuz = [|for a in 0 .. size .. 100 do yield foo.[a..a+size] |]
Но что, если бы мы использовали вместо него список? Каждый вызов к foo.[a..a+size]
занимал бы все больше и больше времени, вся операция O(n^2)
, что делает ее довольно непригодной для задания.
В большинстве случаев, нарезание списка - неправильный подход. Обычно мы используем выравнивание по шаблону для перемещения и манипулирования списками.
Предпочитаемый метод нарезки списка?
По возможности используйте выравнивание по шаблону. В противном случае, вы можете вернуться к Seq.skip
и Seq.take
, чтобы вырезать списки и последовательности для вас:
> [1 .. 10] |> Seq.skip 3 |> Seq.take 5 |> Seq.toList;;
val it : int list = [4; 5; 6; 7; 8]