É uma estrutura de dados que contém uma série de dados ordenados, chamados "elementos". Os elementos são referenciados por número ordinal, primeiro elemento é 1, segundo 2... Os elementos podem ser de qualquer tipo, caracter, numérico, data etc.
Você lembra do conceito de Matriz quando nas épocas de colégio, em Matemática??? Pois é, a mesmíssima coisa!
Um Array ou matriz é uma variável em clipper que armazena vários valores, onde tais valores são armazenados e consultados através de sua posição na matriz.
Vejamos um exemplo de uma matriz numérica de 4x3 (4 linhas e 3 colunas):
Que poderia ser representada assim:
Onde cada anm é um valor da matriz. Por exemplo, se você quisesse saber o valor de a32 na matriz B você encontraria o número 25. Analogamente os outros valores.
Vejamos outro exemplo, agora de uma matriz de uma só coluna, de 3x1 (3 linhas e 1 coluna), também conhecida de Vetor (só quando uma coluna):
Que poderia ser representada assim:
Onde cada anm é um valor da matriz. Por exemplo, se você quisesse saber o valor de a21 na matriz C você encontraria o número 7. Analogamente os outros valores.
Agora que você entendeu bem a idéia, vamos traduzir isso para linguagem Clipper:
A matriz B poderia ser contruída em Clipper da seguinte maneira, compare com a imagem:
Em Clipper: | Na Matemática: |
// definindo a matriz: B := ARRAY(4,3) // atribuindo valores |
Outra forma em Clipper, atribuição dinâmica de uma matriz:
Em Clipper: | Na Matemática: |
// definindo a matriz: // atribuindo valores |
Para consultar o valor de a32 da matriz B em clipper você poderia usar:
? B[3][2]
A matriz C poderia ser contruída em Clipper da seguinte maneira, compare com a imagem:
Em Clipper: | Na Matemática: |
// definindo a matriz: C := ARRAY(3) // atribuindo valores |
Outra forma em Clipper, atribuição dinâmica de uma matriz:
Em Clipper: | Na Matemática: |
// definindo a matriz: // atribuindo valores |
Para consultar o valor de a21 da matriz C em clipper você poderia usar:
? C[2]
Atenção: Se você colocar uma posição além do tamanho do array, o sistema retornará um erro de BASE/1132 Bound error: array access porque o elemento referenciado não existe. Por exemplo, se fizéssemos ? C[4] na matriz C citada acima, suscitaria este erro, pois C[4] não existe!
Ok, agora vamos para outro passo.
Para se buscar um valor dentro do Array, usa-se a função ASCAN(), vamos recordar sua sintaxe:
ASCAN(<aARRAY>, <expPROCURA>,[<nINICIO>], [<nCONTAGEM>])
Onde:
aARRAY = Array onde se fará a pesquisa.
expPROCURA = Expressão de procura, pode ser um valor de qualquer tipo (caracter, numerico, data ou lógico) ou um bloco de código (code block).
nINICIO = Opcional. Valor númerico que representa o elemento inicial de pesquisa, qual a posição do Array que deve iniciar a pesquisa. Se omitido, o valor padrão será 1 (inicio do array)
nCONTAGEM = Opcional. O número de elementos que irá pesquisar a partir de nINICIO. Se omitido, o valor padrão será o tamanho do array ( LEN(aARRAY) ).
ASCAN() retorna um valor numérico representando a posição do elemento procurado caso este seja encontrado, caso contrário, retornará 0 (zero).
Agora veja alguns dos diversos modos de buscar um valor dentro de um Array, usando a função ASCAN() do Clipper:
Exemplo 1: Busca simples.
aArray := { "Tom", "Mary", "Sue" } ? ASCAN(aArray, "Mary") // Resultado: 2 ? ASCAN(aArray, "mary") // Resultado: 0 ? ASCAN(aArray, { |x| UPPER(x) == "MARY" }) // Resultado: 2
Exemplo 2: Verificar quantas ocorrências de um valor dentro do Array.
aArray := { "Tom", "Mary", "Sue","Mary" } nStart := 1 // Armazena última posição do elemento no Array nAtEnd := LEN(aArray) // tamanho da matriz DO WHILE (nPos := ASCAN(aArray, "Mary", nStart)) > 0 ? nPos, aArray[nPos] // mostra posicao e valor. // Atribui nova posicao inicial e testa // com tamanho da matriz (evitar erro). IF (nStart := ++nPos) > nAtEnd EXIT ENDIF ENDDO
Obs.: A linha: DO WHILE (nPos := ASCAN(aArray, "Mary", nStart)) > 0
é o mesmo que:
nPOS := ASCAN(aArray, "Mary", nStart) DO WHILE nPOS > 0 nPOS := ASCAN(aArray, "Mary", nStart)
Exemplo 3: Este exemplo procura uma matriz bi-dimensional usando um bloco de código (code block). A função retornará a posição da linha do elemento procurado. Note que o parâmetro aVal no bloco de código é uma matriz e que aVal[2] significa coluna 2 da matriz (alí você colocará o número da coluna que você irá procurar):
aArr:={} CLS AADD(aArr,{"um", "dois" }) AADD(aArr,{"três", "quatro"}) AADD(aArr,{"cinco","seis" }) ? ASCAN(aArr, {|aVal| aVal[2] == "quatro"}) // Retornará 2.
Um array é uma variável que contém qualquer outro tipo de variável dentro. Um array não terá necessariamente elementos do mesmo tipo, ou seja, um array pode conter strings, números e data em um mesmo array apesar que normalmente tenha elementos do mesmo tipo.
Portanto, se não conhecemos o valor do elemento aARRAY[1] então ele deve ser testado com um VALTYPE(aARRAY[1]). Daí podemos saber se é do tipo caracter, numérico ou data para fazer os ajustes necessários.
Você vai precisar usar 2 funções: ADEL() e ASIZE().
ADEL() apaga o elemento, mas o tamanho do array continuará o mesmo, pois o último elemento se tornará vazio.
Portanto, será necessário usar o ASIZE() para encolher o array. Vejamos:
X := ASCAN(aBAKS, {|A| UPPER(A[1]) == "."}) ADEL(aBAKS, X) // APAGA ELEMENTO aBAKS := aSIZE(aBAKS, LEN(aBAKS)-1) // ENCOLHE ARRAY
Entretanto, caso você esteja compilando com o xHarbour então poderá usar o terceiro parâmetro .T. para fazer a mesma coisa.
X := ASCAN(aBAKS, {|A| UPPER(A[1]) == "."}) ADEL(aBAKS, X, .T.) // APAGA ELEMENTO E ENCOLHE O ARRAY