FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin for Harbour/xHarbour Hash Table
Posts: 310
Joined: Mon Oct 10, 2005 05:10 AM
Hash Table
Posted: Sat Apr 04, 2015 03:05 AM
Hi All

How can I make a multiple dimensional hash table
Code (fw): Select all Collapse
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
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Hash Table
Posted: Mon Apr 06, 2015 10:01 AM
Hi Colin,
Code (fw): Select all Collapse
    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"
Posts: 310
Joined: Mon Oct 10, 2005 05:10 AM
Re: Hash Table
Posted: Mon Apr 06, 2015 10:10 PM
Hi Carlos

Thanks for your reply but with some great help from Daniel Garcia Gil I was able to resolve the problem.
Code (fw): Select all Collapse
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
Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
Re: Hash Table
Posted: Tue Apr 07, 2015 12:14 AM

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

FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 310
Joined: Mon Oct 10, 2005 05:10 AM
Re: Hash Table
Posted: Tue Apr 07, 2015 01:38 AM

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

Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
Re: Hash Table
Posted: Tue Apr 07, 2015 05:30 AM

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
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Hash Table
Posted: Tue Apr 07, 2015 09:40 AM
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 (fw): Select all Collapse
   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"
Posts: 310
Joined: Mon Oct 10, 2005 05:10 AM
Re: Hash Table
Posted: Tue Apr 07, 2015 11:12 AM

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

Posts: 4840
Joined: Fri Nov 18, 2005 04:52 PM
Re: Hash Table
Posted: Tue Apr 07, 2015 01:55 PM
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 (fw): Select all Collapse
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
FWH 18.05/xHarbour 1.2.3/BCC7/Windows 10
Posts: 989
Joined: Thu Nov 24, 2005 03:01 PM
Re: Hash Table
Posted: Wed Apr 08, 2015 07:12 AM
James,

almost yes! it lacks the aAdd():

Code (fw): Select all Collapse
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 (fw): Select all Collapse
 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"

Continue the discussion