Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo explica como tirar fatias de tipos F# existentes e como definir suas próprias fatias.
Em F#, uma fatia é um subconjunto de qualquer tipo de dados. As fatias são semelhantes aos indexadores, mas em vez de produzir um único valor da estrutura de dados subjacente, elas produzem várias. As fatias usam a sintaxe do .. operador para selecionar o intervalo de índices especificados em um tipo de dados. Para obter mais informações, consulte o artigo de referência de expressão de looping.
Atualmente, o F# tem suporte intrínseco para cortar cadeias de caracteres, listas, matrizes e matrizes multidimensionais (2D, 3D, 4D). O fatiamento é mais comumente usado com matrizes e listas F#. Você pode adicionar o fatiamento aos tipos de dados personalizados usando o GetSlice método em sua definição de tipo ou em uma extensão de tipo no escopo.
Fatiando listas e matrizes do F#
Os tipos de dados mais comuns que são fatiados são as matrizes e listas F#. O exemplo a seguir demonstra como fatiar listas:
// Generate a list of 100 integers
let fullList = [ 1 .. 100 ]
// Create a slice from indices 1-5 (inclusive)
let smallSlice = fullList[1..5]
printfn $"Small slice: {smallSlice}"
// Create a slice from the beginning to index 5 (inclusive)
let unboundedBeginning = fullList[..5]
printfn $"Unbounded beginning slice: {unboundedBeginning}"
// Create a slice from an index to the end of the list
let unboundedEnd = fullList[94..]
printfn $"Unbounded end slice: {unboundedEnd}"
O fatiamento de matrizes é exatamente como listas de fatiamento:
// Generate an array of 100 integers
let fullArray = [| 1 .. 100 |]
// Create a slice from indices 1-5 (inclusive)
let smallSlice = fullArray[1..5]
printfn $"Small slice: {smallSlice}"
// Create a slice from the beginning to index 5 (inclusive)
let unboundedBeginning = fullArray[..5]
printfn $"Unbounded beginning slice: {unboundedBeginning}"
// Create a slice from an index to the end of the list
let unboundedEnd = fullArray[94..]
printfn $"Unbounded end slice: {unboundedEnd}"
Antes do F# 6, o fatiamento usava a sintaxe expr.[start..finish] com o extra .. Se você escolher, ainda poderá usar essa sintaxe. Para obter mais informações, consulte RFC FS-1110.
Fatiando matrizes multidimensionais
O F# dá suporte a matrizes multidimensionais na biblioteca principal F#. Assim como acontece com matrizes unidimensionais, fatias de matrizes multidimensionais também podem ser úteis. No entanto, a introdução de dimensões adicionais exige uma sintaxe ligeiramente diferente para que você possa tomar fatias de linhas e colunas específicas.
Os exemplos a seguir demonstram como fatiar uma matriz 2D:
// Generate a 3x3 2D matrix
let A = array2D [[1;2;3];[4;5;6];[7;8;9]]
printfn $"Full matrix:\n {A}"
// Take the first row
let row0 = A[0,*]
printfn $"{row0}"
// Take the first column
let col0 = A[*,0]
printfn $"{col0}"
// Take all rows but only two columns
let subA = A[*,0..1]
printfn $"{subA}"
// Take two rows and all columns
let subA' = A[0..1,*]
printfn $"{subA}"
// Slice a 2x2 matrix out of the full 3x3 matrix
let twoByTwo = A[0..1,0..1]
printfn $"{twoByTwo}"
Definindo fatias para outras estruturas de dados
A biblioteca de núcleos F# define fatias para um conjunto limitado de tipos. Se você quiser definir fatias para mais tipos de dados, poderá fazê-lo na própria definição de tipo ou em uma extensão de tipo.
Por exemplo, veja como você pode definir fatias para a ArraySegment<T> classe para permitir a manipulação conveniente de dados:
open System
type ArraySegment<'TItem> with
member segment.GetSlice(start, finish) =
let start = defaultArg start 0
let finish = defaultArg finish segment.Count
ArraySegment(segment.Array, segment.Offset + start, finish - start)
let arr = ArraySegment [| 1 .. 10 |]
let slice = arr[2..5] //[ 3; 4; 5]
Outro exemplo usando o e ReadOnlySpan<T> os Span<T> tipos:
open System
type ReadOnlySpan<'T> with
member sp.GetSlice(startIdx, endIdx) =
let s = defaultArg startIdx 0
let e = defaultArg endIdx sp.Length
sp.Slice(s, e - s)
type Span<'T> with
member sp.GetSlice(startIdx, endIdx) =
let s = defaultArg startIdx 0
let e = defaultArg endIdx sp.Length
sp.Slice(s, e - s)
let printSpan (sp: Span<int>) =
let arr = sp.ToArray()
printfn $"{arr}"
let sp = [| 1; 2; 3; 4; 5 |].AsSpan()
printSpan sp[0..] // [|1; 2; 3; 4; 5|]
printSpan sp[..5] // [|1; 2; 3; 4; 5|]
printSpan sp[0..3] // [|1; 2; 3|]
printSpan sp[1..3] // |2; 3|]
As fatias internas do F# são end-inclusive
Todas as fatias intrínsecas em F# são end-inclusive; ou seja, o limite superior é incluído na fatia. Para uma determinada fatia com índice x inicial e índice yfinal, a fatia resultante incluirá o valor de yth .
// Define a new list
let xs = [1 .. 10]
printfn $"{xs[2..5]}" // Includes the 5th index
Fatias vazias de F# internas
Listas, matrizes, sequências, cadeias de caracteres, matrizes multidimensionais (2D, 3D, 4D) produzirão uma fatia vazia se a sintaxe puder produzir uma fatia que não existe.
Considere o seguinte exemplo:
let l = [ 1..10 ]
let a = [| 1..10 |]
let s = "hello!"
let emptyList = l[-2..(-1)]
let emptyArray = a[-2..(-1)]
let emptyString = s[-2..(-1)]
Importante
Os desenvolvedores do C# podem esperar que eles gerem uma exceção em vez de produzir uma fatia vazia. Essa é uma decisão de design enraizada no fato de que coleções vazias compõem em F#. Uma lista F# vazia pode ser composta com outra lista F#, uma cadeia de caracteres vazia pode ser adicionada a uma cadeia de caracteres existente e assim por diante. Pode ser comum usar fatias com base em valores passados como parâmetros e ser tolerante a fora dos limites > produzindo uma coleção vazia se ajusta à natureza composicional do código F#.
Fatias de índice fixo para matrizes 3D e 4D
Para matrizes F# 3D e 4D, você pode "corrigir" um índice específico e fatiar outras dimensões com esse índice fixo.
Para ilustrar isso, considere a seguinte matriz 3D:
z = 0
| x\y | 0 | 1 |
|---|---|---|
| 0 | 0 | 1 |
| 1 | 2 | 3 |
z = 1
| x\y | 0 | 1 |
|---|---|---|
| 0 | 4 | 5 |
| 1 | 6 | 7 |
Se você quiser extrair a fatia [| 4; 5 |] da matriz, use uma fatia de índice fixo.
let dim = 2
let m = Array3D.zeroCreate<int> dim dim dim
let mutable count = 0
for z in 0..dim-1 do
for y in 0..dim-1 do
for x in 0..dim-1 do
m[x,y,z] <- count
count <- count + 1
// Now let's get the [4;5] slice!
m[*, 0, 1]
A última linha corrige os índices e z os y índices da matriz 3D e usa o restante dos x valores que correspondem à matriz.