Page 1 of 1
Hash Table
Posted: Sat Apr 04, 2015 3:05 am
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
Re: Hash Table
Posted: Mon Apr 06, 2015 10:01 am
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] } )
Re: Hash Table
Posted: Mon Apr 06, 2015 10:10 pm
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
Re: Hash Table
Posted: Tue Apr 07, 2015 12:14 am
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
Re: Hash Table
Posted: Tue Apr 07, 2015 1:38 am
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
Re: Hash Table
Posted: Tue Apr 07, 2015 5:30 am
by James Bott
Very cool. I expect lots of us are going to be doing something like that soon.
Re: Hash Table
Posted: Tue Apr 07, 2015 9:40 am
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
Re: Hash Table
Posted: Tue Apr 07, 2015 11:12 am
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
Re: Hash Table
Posted: Tue Apr 07, 2015 1:55 pm
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
Re: Hash Table
Posted: Wed Apr 08, 2015 7:12 am
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