Hash Table

Post Reply
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Hash Table

Post by Colin Haig »

Hi All

How can I make a multiple dimensional hash table

Code: Select all

hUser2  := hb_hash()
for i := 1 to len(aData)
   hb_hSet(hUser2,"Description",aData[i,1])
   hb_hSet(hUser2,"Total",aData[i,2]
next

//  I need the hash table to be like a multi dimensional array 
// ["Description"] [i]   
 
Regards

Colin
Carlos Mora
Posts: 988
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Hash Table

Post by Carlos Mora »

Hi Colin,

Code: Select all

    hUser2  := { "Description" => Array( len(aData) ), "Total" => Array( len(aData) ) } 
    aEval( aData, {|x,i| hUser2["Description"][i] := x[1], hUser2["Total"][i] := x[2] } )
 
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Re: Hash Table

Post by Colin Haig »

Hi Carlos

Thanks for your reply but with some great help from Daniel Garcia Gil I was able to resolve the problem.

Code: Select all


aLines := {}
for i := 1 to len(aData)
     hUser2  := hb_hash()
     hb_hSet(hUser2,"Description",aData[i,1])
     hb_hSet(hUser2,"Total",aData[i,2])
     hb_hSet(hUser2,"Account",{=>})
     hb_hSet(hUser2["Account"],"UID",aData[i,3])
     hb_hSet(hUser2,"TaxCode",{=>})
     hb_hSet(hUser2["TaxCode"],"UID",cClTaxUid)
     hb_hSet(hUser2,"FreightTaxCode",{=>})
     hb_hSet(hUser2["FreightTaxCode"],"UID",cClTaxUid)
     aadd(aLines,hUser2)
 next
 hb_hSet(hUser1,"Lines",aLines)
 


Regards

Colin
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: Hash Table

Post by James Bott »

Colin,

OK, I'm curious. I can see you are working with order or invoice data, but why the hash table? I know what hash tables are but I don't know what they really offer. Why use a hash table over a DBF or array?

James
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Re: Hash Table

Post by Colin Haig »

Hi James

I am doing an interface to an accounting package using HTTP Restful API - and the hash tables are passed to a function to convert to JSON
which is the format the API requires. I must say that Daniel Garcia Gil has been a great help to me in resolving issues with the API.

Regards

Colin
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: Hash Table

Post by James Bott »

Very cool. I expect lots of us are going to be doing something like that soon.
FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Carlos Mora
Posts: 988
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Hash Table

Post by Carlos Mora »

Hi Colin,
Colin Haig wrote:Hi Carlos

Thanks for your reply but with some great help from Daniel Garcia Gil I was able to resolve the problem.
glad to hear that you solved the problem. I would be nice to post the answer, usually other coleagues can also find the solution and take advantage of it, specially with the new features of Harbour. In this particular case, I agree with James, JSON and stuff like that related to the internet and services are where thing are moving to.
Anyway, the solutions you posted works slightly differently from what was asked in the original post, that was ["field"] in first term, then [index]. The code you posted is [index]["field"], isn't it? Let me suggest sth:
In Harbour you can write code of hashes straight in your code like we used to do with arrays, but using the => operator, so the whole inner loop block can be changed to something more readable like

Code: Select all

   hUser2  := { "Description" => aData[i,1] ;
              , "Total" => aData[i,2] ;
              , "Account" => { "UID" => aData[i,3] } ;
              , "TaxCode" => { "UID" => cClTaxUid } ;
              , "FreightTaxCode" => { "UID" => cClTaxUid } ;
              }
 
No functions call, just operators. Hash function names have names hard to remember (at least for me ;) )!

Regards
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Colin Haig
Posts: 310
Joined: Mon Oct 10, 2005 5:10 am

Re: Hash Table

Post by Colin Haig »

Hi Carlos

The code I posted was the solution - loop through the items - add the item to the aLines array
aadd(aLines,hUser2)

then pass the aLines array to the record

hb_hSet(hUser1,"Lines",aLines)

Perhaps I should have posted the API documentation so people could see what I wanted to achieve.

It is not until you start doing things like this you realise how much can be done with Harbour/Fivewin

Regards

Colin
User avatar
James Bott
Posts: 4654
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA
Contact:

Re: Hash Table

Post by James Bott »

Carlos,

Are you saying that the code you posted is the equivalent of all the code between the FOR/NEXT in Colin's code? So the entire code would be this:

Code: Select all

aLines := {}
for i := 1 to len(aData)
   hUser2  := { "Description" => aData[i,1] ;
              , "Total" => aData[i,2] ;
              , "Account" => { "UID" => aData[i,3] } ;
              , "TaxCode" => { "UID" => cClTaxUid } ;
              , "FreightTaxCode" => { "UID" => cClTaxUid } ;
              }
 next
 hb_hSet(hUser1,"Lines",aLines)

 
James
Carlos Mora
Posts: 988
Joined: Thu Nov 24, 2005 3:01 pm
Location: Madrid, España

Re: Hash Table

Post by Carlos Mora »

James,

almost yes! it lacks the aAdd():

Code: Select all

aLines := {}
for i := 1 to len(aData)
   hUser2  := { "Description" => aData[i,1] ;
              , "Total" => aData[i,2] ;
              , "Account" => { "UID" => aData[i,3] } ;
              , "TaxCode" => { "UID" => cClTaxUid } ;
              , "FreightTaxCode" => { "UID" => cClTaxUid } ;
              }
   aAdd( aLines, hUser2 )  /// <--------- This one
 next
 // Following the concept, the next one can be 
 // hb_hSet(hUser1,"Lines",aLines)
 hUser1["Lines"]:= aLines
// -- or, if it hasnt been initialized
hUser1:= { "Lines" => aLines }
 
A working sample, with the same structure

Code: Select all

 LOCAL aLines, i, hUser1
 aLines:= Array(200)
 for i := 1 to len(aLines)
   aLines[i]:= { "Description" => i*10+1 ;
              , "Total" => i*10+2 ;
              , "Account" => { "UID" => i*10+3 } ;
              , "TaxCode" => { "UID" => i*10+4 } ;
              , "FreightTaxCode" => { "UID" => i*10+5 } ;
              }

 next
 hUser1:= { "Lines" => aLines }
 
 MsgInfo( hUser1["Lines"][3]["Account"]["UID"] ) // -> Should output 33

 
Saludos
Carlos Mora
http://harbouradvisor.blogspot.com/
StackOverflow http://stackoverflow.com/users/549761/carlos-mora
“If you think education is expensive, try ignorance"
Post Reply