Нарезка как функциональность из списка в F #

С массивом let foo = [|1;2;3;4|] я могу использовать любое из следующего, чтобы вернуть срез из массива.

foo.[..2] 
foo.[1..2] 
foo.[2..]

Как я могу сделать то же самое для List let foo2 = [1;2;3;4]? Когда я пытаюсь использовать тот же синтаксис, что и массив, я получаю error FS00039: The field, constructor or member 'GetSlice' is not defined.

Какой предпочтительный метод получения подраздела списка и почему он не создан для поддержки GetSlice?

Ответы

Ответ 1

Какой предпочтительный метод получения подраздел списка и почему построена для поддержки 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]

Ответ 2

F # 4.0 позволит разрезать синтаксис списков (ссылка).

Обоснование здесь:

Тип списка F # уже поддерживает оператор индекса xs. [3]. Это сделано, несмотря на то, что списки связаны списками в F # - списки так часто используются в F #, что в F # 2.0 было решено поддержать это.

Поскольку поддерживается синтаксис индекса, имеет смысл также поддерживать синтаксис F # slicing, например. хз. [3..5]. Очень странно переходить к типу массива для использования среза, но вам не нужно делать этот переключатель для индексирования.

Тем не менее, Джульетта отвечает, говоря, что большая часть времени, набирая список, является неправильным подходом, по-прежнему сохраняется. Поэтому будьте разумны при использовании этой функции.