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

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

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

Mensagem 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"}}
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

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

Mensagem 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 
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

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

Mensagem por asimoes »

Obrigado Jairo!
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
fladimir
Colaborador
Colaborador
Mensagens: 2445
Registrado em: 15 Nov 2006 20:21

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

Mensagem 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
Sun Tzu há mais de três mil anos cita nas epígrafes de seu livro “A Arte da Guerra“:

“Concentre-se nos pontos fortes, reconheça as fraquezas, agarre as oportunidades e proteja-se contra as ameaças”.
“Se não é vantajoso, nunca envie suas tropas; se não lhe rende ganhos, nunca utilize seus homens; se não é uma situação perigosa, nunca lute uma batalha precipitada”
.


Até 2017    Desktop Console [ Legado ] Harbour | MinGW | DBF | CDX | FastReport | MySQL


Novos Projetos:

   Desktop Visual           Windev Desktop
   Celular Android/iOS   Windev Mobile
   WEB                            Windev Web


Sejamos gratos a Deus.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

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

Mensagem 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" } )
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

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

Mensagem 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.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

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

Mensagem 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.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

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

Mensagem 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.
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Claudio Soto
Colaborador
Colaborador
Mensagens: 566
Registrado em: 27 Ago 2012 12:31
Localização: Uruguay
Contato:

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

Mensagem 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
Saludos.
Dr. Claudio Soto
(Uruguay)
http://srvet.blogspot.com
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

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

Mensagem 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.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

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

Mensagem 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
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

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

Mensagem 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
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Responder