Página 1 de 1

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 09:54
por asimoes
Pessoal,

Tem como saber, dado um array se ele tem 1 dimensão ou mais de 1 dimensão:

Código: Selecionar todos

ex. a:={"teste", "teste"}
      a:={{"TESTE", "TESTE"}}

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 10:32
por Jairo Maia
Olá Alexandre,

Veja se ajuda:

Código: Selecionar todos

Function Main()

 Local aTeste
 
 aTeste:={Nil,Nil}  // unidimensional
 
 If ValType( ATail( aTeste ) ) != "A"
  Hb_Alert( "aTeste é uma Matriz Unidimensional" )
 Else
  Hb_Alert( "aTeste é uma Matriz Bidimensional" )
 EndIf
 
 aTeste:={{Nil,Nil}}  // bidimensional

 If ValType( ATail( aTeste ) ) != "A"
  Hb_Alert( "aTeste é uma Matriz Unidimensional" )
 Else
  Hb_Alert( "aTeste é uma Matriz Bidimensional" )
 EndIf
 
Return Nil 

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 11:08
por asimoes
Obrigado Jairo!

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 12:10
por fladimir
E no caso de mais de 2 dimensões? Da pra fazer um FOR NEXT será?

Desculpe a pergunta é q apesar de não ser autor do tópico fiquei na dúvida pra no caso de mais q 1/2 dimensões.

Fora isto q bom q todo dia aprendemos algo...

[]'s

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 12:39
por alxsts
Olá!

@Jairo: tem certeza de que a lógica do teu exemplo funciona?

Imagine este array

Código: Selecionar todos

a := { { "TESTE", "TESTE" }, "Teste"}

Código: Selecionar todos

LOCAL aArray, a, lMulti := .F.

aArray :=  { { "TESTE", "TESTE" }, "Teste"}

For Each a in aArray
   If Valtype( a ) == "A"
      lMulti := .T.
      Exit
   ENdif
Next

Hb_Alert( { "O tipo do array é", If( lMulti, "Multidimensional", "Unidimensional" } )

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 14:51
por Jairo Maia
Olá Pessoal,

Alexandre Santos, larga a mão de ser legal cara. Rs....
alxsts escreveu:@Jairo: tem certeza de que a lógica do teu exemplo funciona?
Claro que sim. Estamos falando em matriz unidimensional e bimensional, seu exemplo apresenta uma matriz TRIdimensional (se é que existe). Pode mostrar um exemplo de como acessar esse terceiro elemento?

Nota: Isso porque não vi lógica programática para uso desse tipo de matriz.

Fladimir:
fladimir escreveu:E no caso de mais de 2 dimensões? Da pra fazer um FOR NEXT será?
Não. Tenho situações que numa mesma matriz ela guarda outras matrizes. Quando é o caso, basta usar a lógica dos eixos "X" e "Y" da matriz. Algo como aTestes[1,1,2,3]. Uso isso. Oportunamente posso até montar um exemplo. Sem problemas.

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 17:05
por alxsts
Olá!
Jairo Maia escreveu: seu exemplo apresenta uma matriz TRIdimensional (se é que existe). Pode mostrar um exemplo de como acessar esse terceiro elemento?
O array que mostrei é um array aninhado (nested). Em xBase, não há limite para a quantidade de dimensões de um array, a não ser a memória disponível.

Segue o exemplo:

Código: Selecionar todos

Function Main()

   LOCAL aArray :=  { { "TESTE", "TESTE" }, "Teste"}

   SetMode( 25,80 )

   Hb_Alert( { "aArray[ 1, 1 ] ; ", aArray[ 1, 1 ] } )
   Hb_Alert( { "aArray[ 1, 2 ] ; ", aArray[ 1, 2 ] } )   
   Hb_Alert( { "aArray[ 2 ]    ; ", aArray[ 2 ]    } )

   Jairo( aArray )
   Alexandre( aArray )

RETURN NIL

//---------------------------------------------------------------

STATIC Function Jairo( aArray )

 Local aTeste
 
 aTeste:={Nil,Nil} // unidimensional
 
 If ValType( ATail( aTeste ) ) != "A"
 Hb_Alert( "aTeste é uma Matriz Unidimensional" )
 Else
 Hb_Alert( "aTeste é uma Matriz Bidimensional" )
 EndIf
 
 aTeste:={{Nil,Nil}} // bidimensional

 If ValType( ATail( aTeste ) ) != "A"
 Hb_Alert( "aTeste é uma Matriz Unidimensional" )
 Else
 Hb_Alert( "aTeste é uma Matriz Bidimensional" )
 EndIf
 
 aTeste:= aArray // Nested Array ou array aninhado

 If ValType( ATail( aTeste ) ) != "A"
 Hb_Alert( "aTeste é uma Matriz Unidimensional" )
 Else
 Hb_Alert( "aTeste é uma Matriz Bidimensional" )
 EndIf

Return Nil 

//--------------------------------------------------

STATIC FUNCTION Alexandre( aArray )

LOCAL a, lMulti := .F.

For Each a in aArray
 If Valtype( a ) == "A"
   lMulti := .T.
   Exit
 ENdif
Next

Hb_Alert( { "O tipo do array é", If( lMulti, "Multidimensional", "Unidimensional" ) } )

RETURN NIL

//--------------------------------------------------
Jairo Maia escreveu:Nota: Isso porque não vi lógica programática para uso desse tipo de matriz.
Nos tempos do Clipper, quando não havia Hash, usava-se muito este tipo de array. Imagine varrer uma tabela de títulos a receber, ordenada por cliente, buscando os títulos em atraso. Para cada título, posso fazer:

Código: Selecionar todos

AAdd( aTitulos, { nrTitulo, dtVencto, vlTitulo }, cdCli } )
Quanto à questão do Fladimir, não vejo problema algum em usar For ... Next. Só que estes For ... Next terão que ser aninhados e em número igual ao das dimensões do array principal.

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 17:16
por Jairo Maia
Olá amigo Alexandre,

Mas onde está o exemplo para acessar o elemento 3?

Você postou um exemplo que acessa o elemento 1 e 2. Altere o elemento 3 para por exemplo "algoz", e quero ver como acessá-lo.

A rigor, estou curioso pra caramba.

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 17:29
por Claudio Soto
Para recorrer todos los elementos de una matriz de cualquier dimensión se puede usar la recursividad, ver ej.

http://www.hmgforum.com/viewtopic.php?f=9&t=2526

PD: este ejemplo lo desarrolle antes de saber que hb tenía una tal función llamada hb_valtoexp :% , por lo menos desarrollarlo me sirvió para sacar un poco el óxido de mis neuronas :D

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 18:51
por alxsts
Olá meu caro Jairo!

A matriz só tem dois elementos! Como vou acessar o terceiro, se não existe?

É uma matriz (ou array). Dentro dela tenho dois elementos, sendo o primeiro um outro array (sub array ou nested array), com dois elementos, e o segundo elemento,que é uma string. Talvez isto te faça enxergar três elementos.
Jairo Maia escreveu:Mas onde está o exemplo para acessar o elemento 3?
Você postou um exemplo que acessa o elemento 1 e 2. Altere o elemento 3 para por exemplo "algoz", e quero ver como acessá-lo.
Veja a linha Hb_Alert( { "aArray[ 2 ] ; ", aArray[ 2 ] } ). Ela exibe os dois elementos ( aArray[ 1, 1 ] e aArray[ 1, 2 ] ) do sub array (que é o elemento 1 de aArray) e depois exibe o segundo elemento de aArray (aArray[ 2 ]):

Código: Selecionar todos

Function Main()

   LOCAL aArray :=  { { "TESTE", "TESTE" }, "Algoz"}

   SetMode( 25,80 )

   Hb_Alert( { "aArray[ 1, 1 ] ; ", aArray[ 1, 1 ] } )
   Hb_Alert( { "aArray[ 1, 2 ] ; ", aArray[ 1, 2 ] } )   
   Hb_Alert( { "aArray[ 2 ]    ; ", aArray[ 2 ]    } )

RETURN NIL

//---------------------------------------------------------------
Outras coisas:

Código: Selecionar todos


LOCAL aArray :=  { { "TESTE", "TESTE" }, "Algoz"}

? Len( aArray ) //---> 2
? Len( aArray[ 1 ] ) //---> 2
? Len( aArray[ 2 ] ) //---> 5
? ValType( aArray ) //---> "A"
? ValType( aArray[ 1 ] ) //---> "A"
? ValType( aArray[ 2 ] ) //---> "C"
Talvez o exemplo dos títulos deixe mais clara a situação:

Código: Selecionar todos

AAdd( aTitulos, { nrTitulo, dtVencto, vlTitulo }, cdCli } )

{ nrTitulo, dtVencto, vlTitulo }, cdCli

20          22/10/2016    500,00   2058
30          31/12/2016  1.500,00   2058
421         15/01/2017    560,00   2058
524         31/01/2017    230,00   4356
602         30/11/2016    750,00   8055
650         15/12/2016    990,00   8055
Ficaria como se fosse uma tabela .DBF.

Obrigado Dr. Claudio por sua contribuição. Recursividade é um assunto interessante e muito ligado a arrays.

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 21:02
por JoséQuintas
Sobre trabalhar com o array multidimensional, acho que um muito usado é este:

Código: Selecionar todos

aFiles := Directory( "*.*" )
FOR nCont = 1 TO Len( aFiles )
   ? aFiles[ nCont, F_NAME ]
NEXT

Array de 1 dimensão ou 2 ou mais dimensões

Enviado: 07 Mar 2017 21:14
por JoséQuintas
E sobre o exemplo do ASimões, dependendo do caso pode ser interessante usar 3 dimensões.

Código: Selecionar todos

#define X_CLIENTE 1
#define X_DOCLIST 2
#define X_NUMERO 1
#define X_DATA 2
#define X_VALOR 3
aArray := {  { cliente, { { numero, data, valor },  { numero, data, valor } } }, { cliente, { { numero, data, valor }, { numero, data, valor } } } }

FOR EACH oCliente IN aArray
   FOR EACH oDocto IN oCliente[ X_DOCLIST ]
      ? oCliente[ X_CLIENTE ], oDocto[ X_NUMERO ], oDocto[ X_DATA ], oDocto[ X_VALOR ]
   NEXT
NEXT