Convertir Hash a Array "organizado" *SOLUCIONADO*

Convertir Hash a Array "organizado" *SOLUCIONADO*

Postby VictorCasajuana » Wed Jan 06, 2021 9: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: Select all  Expand view  RUN
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: Select all  Expand view  RUN
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:
Image


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) :
Image

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!
Last edited by VictorCasajuana on Sun Jan 24, 2021 6:08 pm, edited 1 time in total.
--------
¿ Y porque no ?
¿ And why not ?
User avatar
VictorCasajuana
 
Posts: 265
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs

Re: Convertir Hash a Array "organizado" *SOLUCIONADO*

Postby VictorCasajuana » Wed Jan 06, 2021 3:37 pm

bueno, me lo he tomado como un kata. Lo dejo aquí por si a alguien le sirve:

Code: Select all  Expand view  RUN
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 ?
User avatar
VictorCasajuana
 
Posts: 265
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs

Re: Convertir Hash a Array "organizado"

Postby nageswaragunupudi » Wed Jan 06, 2021 5:38 pm

You can view the array of hashes as you wanted without any conversion directly with Xbrowse

Code: Select all  Expand view  RUN
#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


Image

We can also edit the values in the hashes directly.

Code: Select all  Expand view  RUN
#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


Image
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10662
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Convertir Hash a Array "organizado" *SOLUCIONADO*

Postby nageswaragunupudi » Wed Jan 06, 2021 7:16 pm

VictorCasajuana wrote:bueno, me lo he tomado como un kata. Lo dejo aquí por si a alguien le sirve:

Code: Select all  Expand view  RUN
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
User avatar
nageswaragunupudi
 
Posts: 10662
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Convertir Hash a Array "organizado"

Postby VictorCasajuana » 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: Select all  Expand view  RUN
oTable():New():Insert({{'codigo'=>1,'nombre'=>'Jose','numero'=>12},{'codigo'=>'2','nombre'=>'Maria','numero'=>5}})


makes this string:
Code: Select all  Expand view  RUN
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 ?
User avatar
VictorCasajuana
 
Posts: 265
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs

Re: Convertir Hash a Array "organizado"

Postby cnavarro » Thu Jan 07, 2021 11:27 am

Victor, muy buena la funcioncilla, enhorabuena
Para los headers, yo lo tenía hecho así
Code: Select all  Expand view  RUN

    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
User avatar
cnavarro
 
Posts: 6549
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: Convertir Hash a Array "organizado"

Postby VictorCasajuana » 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" :wink:

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

Salud!
--------
¿ Y porque no ?
¿ And why not ?
User avatar
VictorCasajuana
 
Posts: 265
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs

Re: Convertir Hash a Array "organizado"

Postby nageswaragunupudi » Thu Jan 07, 2021 2: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
User avatar
nageswaragunupudi
 
Posts: 10662
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Convertir Hash a Array "organizado"

Postby VictorCasajuana » Thu Jan 07, 2021 2: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 ?
User avatar
VictorCasajuana
 
Posts: 265
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs

Re: Convertir Hash a Array "organizado"

Postby nageswaragunupudi » Thu Jan 07, 2021 4:10 pm

Testing:

Code: Select all  Expand view  RUN
#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
 


Image
Regards

G. N. Rao.
Hyderabad, India
User avatar
nageswaragunupudi
 
Posts: 10662
Joined: Sun Nov 19, 2006 5:22 am
Location: India

Re: Convertir Hash a Array "organizado"

Postby VictorCasajuana » Thu Jan 07, 2021 6:13 pm

I include your test in my testing... :D

Code: Select all  Expand view  RUN

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!
Image
--------
¿ Y porque no ?
¿ And why not ?
User avatar
VictorCasajuana
 
Posts: 265
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: Adolfo, gmart1, Google [Bot] and 76 guests