FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour Convertir Hash a Array "organizado" *SOLUCIONADO*
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Convertir Hash a Array "organizado" *SOLUCIONADO*
Posted: Wed Jan 06, 2021 09:31 AM
Hola.

Necesito pasar un Hash a un array "organizado" para un proceso posterior, xBrowse() lo hace perfectamente para mostrarlo, por lo que supongo hay una función que lo hace pero no la encuentro. Me explico mejor:

a partir de un hash como este:
Code (fw): Select all Collapse
aData:= {;
                { 'codigo' => 'uno',    'nombre' => 'Juan' },;
                { 'codigo' => 'dos',    'nombre' => 'Maria' },;
                { 'codigo' => 'tres',   'nombre' => 'Jose' },;
                { 'codigo' => 'cuatro', 'nombre' => 'Sonia' },;
                { 'nombre' => 'Pedro',  'codigo' => 'cinco' },;
                { 'edad'   => 18,       'codigo' => 'seis' };
    }


me gustaría obtener este:

Code (fw): Select all Collapse
aDataCorrecto:= {;
                { 'codigo','nombre','edad'},;
                { 'uno',   'Juan',  0},;
                { 'dos',   'Maria', 0},;
                { 'tres',  'Jose',  0},;
                { 'cuatro','Sonia', 0},;
                { 'cinco', 'Pedro', 0},;
                { 'seis',  '',     18};
    }


He probado con ArrTranspose() pero me devuelve un array con los Hash:



Si hago un xBrowse(aData) me muestra esto que es lo que necesitaría (teniendo en cuenta que las cabeceras serían el primer item del array que necesito) :


Puedo montar la función que lo hace y publicarla en el foro, pero es por no reinventar la rueda si ya está echo...

Gracias y Salud!
--------

¿ Y porque no ?

¿ And why not ?
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Convertir Hash a Array "organizado" *SOLUCIONADO*
Posted: Wed Jan 06, 2021 03:37 PM
bueno, me lo he tomado como un kata. Lo dejo aquí por si a alguien le sirve:

Code (fw): Select all Collapse
Static Function ArrayHashToArray( aData )

    Local aReturn  := Array( 0 )
    Local hItems   := { => }
    Local hItem    := { => }
    Local aHeaders := Array( 0 )
    Local aRow     := Array( 0 )
    Local nPositon := 0

    for each hItems in aData

        for each hItem in hItems

            if aScan( aHeaders, hItem:__enumkey) == 0
                
                aAdd( aHeaders, hItem:__enumkey )

            Endif
            
        next

    next

    aAdD( aReturn, aHeaders )

    for each hItems in aData

        aRow := Array( Len( aHeaders ) )

        for each hItem in hItems

            aRow[ aScan( aHeaders, hItem:__enumkey ) ] := hItem:__enumvalue

        next

        aAdD( aReturn, aRow )

    next

Return ( aReturn )


Salud!
--------

¿ Y porque no ?

¿ And why not ?
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Convertir Hash a Array "organizado"
Posted: Wed Jan 06, 2021 05:38 PM
You can view the array of hashes as you wanted without any conversion directly with Xbrowse

Code (fw): Select all Collapse
#include "fivewin.ch"

function Main()

   local aData:= {;
      { 'codigo' => 'uno',    'nombre' => 'Juan' },;
      { 'codigo' => 'dos',    'nombre' => 'Maria' },;
      { 'codigo' => 'tres',   'nombre' => 'Jose' },;
      { 'codigo' => 'cuatro', 'nombre' => 'Sonia' },;
      { 'nombre' => 'Pedro',  'codigo' => 'cinco' },;
      { 'edad'   => 18,       'codigo' => 'seis' };
   }

   XBROWSER aData FASTEDIT TITLE "ARRAY OF HASHES"

return nil




We can also edit the values in the hashes directly.

Code (fw): Select all Collapse
#include "fivewin.ch"

function Main()

   local aData := { ;
      { 'code' => 'one' ,     'name' => 'John'  } ,;
      { 'code' => 'two' ,     'name' => 'Maria' } ,;
      { 'code' => 'three' ,   'name' => 'Jose'  } ,;
      { 'code' => 'four' ,    'name' => 'Sonia' } ,;
      { 'code' => 'five',     'name' => 'Pedro' } ,;
      { 'age'   => 18 ,       'code' => 'six'   } ;
   }

   XBROWSER aData FASTEDIT TITLE "ARRAY OF HASHES"

   XBROWSER aData FASTEDIT TITLE "ARRAY OF HASHES"

   ? FW_ValToExp( aData )

return nil


Regards



G. N. Rao.

Hyderabad, India
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Convertir Hash a Array "organizado" *SOLUCIONADO*
Posted: Wed Jan 06, 2021 07:16 PM
VictorCasajuana wrote:bueno, me lo he tomado como un kata. Lo dejo aquí por si a alguien le sirve:

Code (fw): Select all Collapse
Static Function ArrayHashToArray( aData )

    Local aReturn  := Array( 0 )
    Local hItems   := { => }
    Local hItem    := { => }
    Local aHeaders := Array( 0 )
    Local aRow     := Array( 0 )
    Local nPositon := 0

    for each hItems in aData

        for each hItem in hItems

            if aScan( aHeaders, hItem:__enumkey) == 0
                
                aAdd( aHeaders, hItem:__enumkey )

            Endif
            
        next

    next

    aAdD( aReturn, aHeaders )

    for each hItems in aData

        aRow := Array( Len( aHeaders ) )

        for each hItem in hItems

            aRow[ aScan( aHeaders, hItem:__enumkey ) ] := hItem:__enumvalue

        next

        aAdD( aReturn, aRow )

    next

Return ( aReturn )


Salud!


Nice function!!!
Liked it very much.
Regards



G. N. Rao.

Hyderabad, India
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Convertir Hash a Array "organizado"
Posted: Thu Jan 07, 2021 10:28 AM
Thank you for the review.

xBrowse displays the information correctly, but I didn't need to show it, I wanted to do the conversion to process it later.

My goal was to do a method to process the data and mount the SQL string for an INSERT INTO with multiple records.

With this function, works fine:
Code (fw): Select all Collapse
oTable():New():Insert({{'codigo'=>1,'nombre'=>'Jose','numero'=>12},{'codigo'=>'2','nombre'=>'Maria','numero'=>5}})


makes this string:
Code (fw): Select all Collapse
INSERT INTO db.table (codigo,nombre,numero) VALUES ('1','Jose','12'),('2','Maria','5')


hash keys should not be sorted with the function

best regards!
--------

¿ Y porque no ?

¿ And why not ?
Posts: 6755
Joined: Wed Feb 15, 2012 08:25 PM
Re: Convertir Hash a Array "organizado"
Posted: Thu Jan 07, 2021 11:27 AM
Victor, muy buena la funcioncilla, enhorabuena
Para los headers, yo lo tenía hecho así
Code (fw): Select all Collapse
    AEval( aData, { | h | AEVal( hb_HKeys( h ), { | c | if( Empty( Ascan( aHeaders, c ) ), AAdd( aHeaders, c ), ) } ) } )

Pero tu código queda muy limpio
Cristobal Navarro

Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo

El secreto de la felicidad no está en hacer lo que te gusta, sino en que te guste lo que haces
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Convertir Hash a Array "organizado"
Posted: Thu Jan 07, 2021 11:37 AM
Gracias Cristobal por el comentario.

Veo que tu código hace lo mismo.

La verdad es que también lo podía reducir con Eval pero a veces meterlo todo en una línea dificulta el posterior mantenimiento.
cita sacada directamente de "The Clean Code" :-)

Intento utilizar los Eval en casos concretos que me ayuden a entender mejor el código que escribo. :-)

Salud!
--------

¿ Y porque no ?

¿ And why not ?
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Convertir Hash a Array "organizado"
Posted: Thu Jan 07, 2021 02:50 PM

Mr. Victor

Sorry, I made the post without actually understanding your requirement. Later I understood when a Spanish friend explained the purpose of your post and I even thought of deleting my post.

Your function is quite elegant. Considering to include it in FWH, if it is ok with you, after making it more generic, if it is ok with you.

Regards



G. N. Rao.

Hyderabad, India
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Convertir Hash a Array "organizado"
Posted: Thu Jan 07, 2021 02:59 PM

Mr. Rao.

Thank you very much for your comment.

You mustn't apologize for anything.

I am delighted that you include this feature in any FWH function.

It'll be a pleasure.

best regards

--------

¿ Y porque no ?

¿ And why not ?
Posts: 10733
Joined: Sun Nov 19, 2006 05:22 AM
Re: Convertir Hash a Array "organizado"
Posted: Thu Jan 07, 2021 04:10 PM
Testing:

Code (fw): Select all Collapse
#include "fivewin.ch"

function Main()

   local aData := ;
   {  {  "date" => date() - 2, "item123" => 10, "item12" => 20 } ;
   ,  {  "date" => date() - 1, "item123" => 30, "item1"  => 40 } ;
   }


   XBROWSER aData TITLE "HASH" NOMODAL
   XBROWSER ArrayHashToArray( aData ) TITLE "ARRAY"

return nil


Regards



G. N. Rao.

Hyderabad, India
Posts: 309
Joined: Wed Mar 28, 2018 04:38 PM
Re: Convertir Hash a Array "organizado"
Posted: Thu Jan 07, 2021 06:13 PM
I include your test in my testing... :-)

Code (fw): Select all Collapse
aData := {{  "date" => 0d20210106 - 2, "item123" => 10, "item12" => 20 },;
               {  "date" => 0d20210106 - 1, "item123" => 30, "item1"  => 40 } ;
              }

::assert():arrayequals({;
                            {'date','item123','item12','item1'},;
                            {0d20210104,10,20,},;
                            {0d20210105,30,,40};
                            }, aData:ArrayHashToArray(), 'Test ArrayHashToArray()')


It works fine!
--------

¿ Y porque no ?

¿ And why not ?

Continue the discussion