Página 1 de 1
Ajuda com organização de um array
Enviado: 24 Dez 2016 21:20
por wmanesco
Boa noite pessoal, estou com problema para organizar um array, preciso de ajuda..
é o seguinte, o código serve para uma integração com google drive, a api me retorna um json com uma lista de arquivos.
Preciso organiza-los em array, tipo assim:
Montei um exemplo para ver se podem me ajudar, no meu código não está bem assim, mas a é a idéia:
O Array estaria assim:
Código: Selecionar todos
{
{
"id" => "2"
"Titulo" => "Fotos"
"parente" => "1"
},
{
"id" => "1"
"Titulo" => "Teste"
"parente" => "" //ou seja, esta na pasta raiz
},
{
"id" => "3"
"Titulo" => "teste.jpg"
"parente" => "2" //dentro de fotos
},
{
"id" => "4"
"Titulo" => "doc.pdf"
"parente" => "1" //dentro de Teste
},
{
"id" => "5"
"Titulo" => "documento.docx"
"parente" => "" //raiz
},
{
"id" => "6"
"Titulo" => "desktop.rar"
"parente" => "" //raiz
}
}
Tentei organiza-lo dessa forma, mas tem alguns bugs e não está ficando 100%.
Código: Selecionar todos
FOR EACH h IN _aFiles
hFile := hb_Hash()
hFile["file" ] := h
hFile["items"] := {}
AAdd( aFiles, hFile )
NEXT
FOR i := Len( aFiles ) TO 1 STEP -1
hFile := aFiles[i]
IF !Empty( hFile["file"]["parente"] )
nPos := AScan( aFiles, { |h| Alltrim( h["file"]["id"] ) == Alltrim( hFile["file"]["parente"] ) } )
IF !Empty( nPos )
AAdd( aFiles[ nPos, "items" ], hFile )
HB_Adel( aFiles, i, .T. )
ENDIF
ENDIF
NEXT
Depois disso, vai ser montado uma TREE com esses itens..
Alguém tem uma idéia para melhorar meu método de ordenação?
Ajuda com organização de um array
Enviado: 25 Dez 2016 10:34
por JoséQuintas
Eu faria parecido com um menu principal.
Código: Selecionar todos
#define GOOGLE_TITULO 1
#define GOOGLE_ID 2
#define GOOGLE_SUB 3
MenuOption( "Teste", 1 )
MenuDrop()
MenuOption( "Fotos", 2 )
MenuDrop()
MenuOption( "teste.jpg", 3 )
MenuUnDrop()
MenuOption( "doc.pdf", 4 )
MenuOption( "Documento.docx", 5 )
MenuOption( "Desktop.rar", 6 )
MenuUnDrop()
/*
Array contendo
oMenu := { "titulo", nId, { suboptions } )
*/
Ajuda com organização de um array
Enviado: 25 Dez 2016 10:41
por JoséQuintas
Apenas como exemplo, um menu principal ilimitado usando esse array, em visual texto, mas estilo W10
Código: Selecionar todos
#include "inkey.ch"
PROCEDURE Main
LOCAL oMenu
SetMode( 25, 80 )
SET EVENTMASK TO INKEY_ALL - INKEY_MOVE
SetColor( "W/B,N/W,,,W/B" )
CLS
oMenu := MenuCria()
DoMenu( oMenu, .T. )
RETURN
FUNCTION DoMenu( oMenu, lPrincipal )
LOCAL oElement, nOpc
hb_Default( @lPrincipal, .F. )
DO WHILE .T.
CLS
FOR EACH oElement IN oMenu
@ oElement:__EnumIndex + 2, 10 PROMPT oElement[ 1 ]
NEXT
IF lPrincipal
@ Row() + 1, 10 PROMPT "Sair"
ELSE
@ 1, 5 PROMPT "<<<<"
ENDIF
MENU TO nOpc
IF LastKey() == K_ESC .OR. nOpc > Len( oMenu )
EXIT
ENDIF
IF Len( oMenu[ nOpc, 2 ] ) > 0
DOMenu( oMenu[ nOpc, 2 ] )
ENDIF
ENDDO
RETURN NIL
Dá 600 linhas de fonte só com as opções do menu, então vai em zip pronto pra compilar.
Ajuda com organização de um array
Enviado: 25 Dez 2016 13:23
por wmanesco
Quintas, obrigado pela resposta.
Esta parte que você me enviou seria mais parecido com a criação da TREE...
Porém a dificuldade está em organiza-lo da forma correta, como está o seu array nesta parte:
No seu caso o array vem certo(por que você que monta), no meu ele vem uma lista apenas indicando seus "parents" e preciso organiza-lo igual está o seu, com um array de itens dentro de outro, para na hora da montagem utilizar recursividade...
JoséQuintas escreveu:
/*
17 Array contendo
18
19 oMenu := { "titulo", nId, { suboptions } )
20 */
Ajuda com organização de um array
Enviado: 25 Dez 2016 13:26
por wmanesco
Então o que eu preciso seria mais parecido com um "método de organização", ainda estou tentando achar um que funcione, tentei outro assim:
Não deu certo, então não tenho mais o código, mas vou tentar mostrar os passos.
1 - Pegar todas as pastas(arquivos que possuem parents) e colocar em um array.
2 - Organiza-las em seus devidos lugares (dentro da raiz ou dentro de outra pasta)
3 - Correr todos os outros itens (que não são pastas) e ir colocando dentro das pastas.
Era pra funcionar? Por que de repente eu cometi um erro no código e por isso não funcionou..
Ajuda com organização de um array
Enviado: 25 Dez 2016 17:57
por JoséQuintas
Por isso mantive um elemento pra guardar a ID.
Usando recursividade pode ir colocando cada elemento no seu lugar.
Ajuda com organização de um array
Enviado: 27 Dez 2016 14:55
por alxsts
Olá!
@William: estou tentando criar uma solução para este problema mas o arquivo JSON postado como exemplo está fora de formato. Poderia postar um arquivo real, no formato correto?
Ajuda com organização de um array
Enviado: 27 Dez 2016 15:39
por JoséQuintas
Código: Selecionar todos
#define OP_ID 1
#define OP_TITULO 2
#define OP_PARENTE 3
PROCEDURE test
LOCAL aOpcoes
aOpcoes := { ;
{ "2", "Fotos", "1" }, ;
{ "1", "Teste", "" }, ;
{ "3", "teste.jpg", "2" }, ;
{ "4", "doc.pdf", "1" }, ;
{ "5", "documento.docx", "" }, ;
{ "6", "desktop.rar", "" } }
ASort( aOpcoes,,, { | a, b | a[ OP_ID ] < b[ OP_ID ] } )
Show( aOpcoes, "", 0, "" )
RETURN
FUNCTION Show( aOpcoes, cParent, nLevel, cPrefixo )
LOCAL oElement, nOpc := 1
FOR EACH oElement IN aOpcoes
IF oElement[ OP_PARENTE ] == cParent
? Space( nLevel ) + cPrefixo + Str( nOpc, 1 ) + "." + oElement[ OP_TITULO ]
Show( aOpcoes, oElement[ OP_ID ], nLevel + 3, cPrefixo + Str( nOpc++, 1 ) + "." )
ENDIF
NEXT
RETURN NIL
Código: Selecionar todos
1.Teste
1.1.Fotos
1.1.1.teste.jpg
1.2.doc.pdf
2.documento.docx
3.desktop.rar
Ajuda com organização de um array
Enviado: 27 Dez 2016 16:53
por alxsts
Olá!
Em meu entendimento, a saída esperada é:
Código: Selecionar todos
> Raiz
documento.docx
desktop.rar
> Teste
> Fotos
teste.jpg
doc.pdf
Ajuda com organização de um array
Enviado: 27 Dez 2016 18:58
por wmanesco
Obrigado pela ajuda pessoal, consegui resolver.. acontece que o id dos arquivos do google não é do tipo sequencial, então não conseguia dar um asort. Porém achei na documentação da API um filtro OrderBy, e setando ele por data de criação já me ajuda... ai o código para organizar ficou este:
Código: Selecionar todos
/*
hParents é uma hash, sendo a chave o ID do arquivo PAI(pasta) e o conteudo é um array de arquivos...
hParents["id"] := {oFile, oFile2, ...}
*/
METHOD organizeFiles() CLASS Drive
LOCAL aFiles := {}, _aFiles := ::oDriveAPI:getDriveFiles():getFiles()
LOCAL oFile, hAddedItems := hb_Hash()
LOCAL hParents
hParents := ::oDriveAPI:getDriveFiles():getFilesParents()
FOR EACH oFile IN _aFiles
IF hb_HHasKey( hAddedItems, oFile:getID() )
LOOP
ENDIF
hFile := hb_Hash()
hFile["file" ] := oFile
hFile["items"] := {}
::addFilesParents( @hFile, oFile, hParents, @hAddedItems )
AAdd( aFiles, hFile )
NEXT
RETURN aFiles
METHOD addFilesParents( hFile, oFile, hParents, hAddedItems ) CLASS Drive
LOCAL hFileAux, oChild
IF hb_HHasKey( hParents, Alltrim( oFile:getID() ) )
FOR EACH oChild IN hParents[ Alltrim( oFile:getID() ) ]
hFileAux := hb_Hash()
hAddedItems[ oChild:getID() ] := ""
hFileAux["file" ] := oChild
hFileAux["items"] := {}
::addFilesParents( @hFileAux, oChild, hParents, @hAddedItems, 2 )
AAdd( hFile["items"], hFileAux )
NEXT
ENDIF
RETURN Self