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: 2822
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP
Curtiu: 2 vezes

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: 3110
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: 2822
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP
Curtiu: 2 vezes

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: 3110
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: 2822
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP
Curtiu: 2 vezes

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: 568
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: 3110
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: 20420
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

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, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (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: 20420
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP
Curtiram: 1 vez

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, multithread, gtwvg, fivewin 25.12, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui), (hmg3), (hmg extended), (oohg), PNotepad, ASP, (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