Convertir Hash a Array "organizado" *SOLUCIONADO*

Post Reply
User avatar
VictorCasajuana
Posts: 30
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs
Contact:

Convertir Hash a Array "organizado" *SOLUCIONADO*

Post by VictorCasajuana »

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

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

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: 30
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs
Contact:

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

Post by VictorCasajuana »

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

Code: Select all

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
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: Convertir Hash a Array "organizado"

Post by nageswaragunupudi »

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

Code: Select all

#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

#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: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

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

Post by nageswaragunupudi »

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

Code: Select all

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
VictorCasajuana
Posts: 30
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs
Contact:

Re: Convertir Hash a Array "organizado"

Post by VictorCasajuana »

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

oTable():New():Insert({{'codigo'=>1,'nombre'=>'Jose','numero'=>12},{'codigo'=>'2','nombre'=>'Maria','numero'=>5}})
makes this string:

Code: Select all

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

Re: Convertir Hash a Array "organizado"

Post by cnavarro »

Victor, muy buena la funcioncilla, enhorabuena
Para los headers, yo lo tenía hecho así

Code: Select all

    AEval( aData, { | h | AEVal( hb_HKeys( h ), { | c | if( Empty( Ascan( aHeaders, c ) ), AAdd( aHeaders, c ), ) } ) } )
 
Pero tu código queda muy limpio
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
User avatar
VictorCasajuana
Posts: 30
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs
Contact:

Re: Convertir Hash a Array "organizado"

Post by VictorCasajuana »

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
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: Convertir Hash a Array "organizado"

Post by nageswaragunupudi »

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
VictorCasajuana
Posts: 30
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs
Contact:

Re: Convertir Hash a Array "organizado"

Post by VictorCasajuana »

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
nageswaragunupudi
Posts: 8017
Joined: Sun Nov 19, 2006 5:22 am
Location: India
Contact:

Re: Convertir Hash a Array "organizado"

Post by nageswaragunupudi »

Testing:

Code: Select all

#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
VictorCasajuana
Posts: 30
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs
Contact:

Re: Convertir Hash a Array "organizado"

Post by VictorCasajuana »

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

Code: Select all

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 ?
Post Reply