mIRC Homepage

HowDo Hash Tables Sort

Posted By: OuttaControlX

HowDo Hash Tables Sort - 11/12/05 06:17 AM

ok im making a script and i need the hash table to sort items in the order they were added (in my opinion mirc should do this by default mad) is there a way for this to be posible? i wrote a 300+ line script depending on my asumption hash tables sorted themselfs by how there were added

1st added item


i really love hash tables, im a hash fanatic and i dont wanna convert my 300+ line script to ini unless i absolutly have to mad

Posted By: hixxy

Re: HowDo Hash Tables Sort - 11/12/05 09:48 AM

I could be wrong but I thought that hashtables were basically unsorted arrays with items added by a key. They don't need an order because you could just give each item a number and loop with $hget(table,N).
Posted By: FiberOPtics

Re: HowDo Hash Tables Sort - 11/12/05 10:01 AM

Instead of asking how to sort hash tables (which is an idiotic thing to do), you should state why exactly you want the hash tables sorted. What you want to do may not even require for you to sort the hash table in the first place.

Btw, when making a script, or in general when working on whatever project in life, an important part of it is thinking/planning ahead. If you only found out now that you need your hash table sorted, then you didn't really think it through when you first took the decision to resort to hash tables. If the order of adding is important, I'd have gone with a hidden window probably.

Note that there are ways to sort the data that is in the hash table when this data is exported to a file or window, with the /filter command, but that's still not sorting the hash table itsself. It's just taking a copy of the data which the hash table holds, and then sorting this copy.

Your unjustified use of the mad smiley is quite aggravating.
Posted By: Kelder

Re: HowDo Hash Tables Sort - 11/12/05 10:56 AM

Use a sequence number as item name to add the data to the hash. Make an extra item 'counter' that contains the next free number and /hinc hashname counter after each /hadd statement.
Posted By: DaveC

Re: HowDo Hash Tables Sort - 11/12/05 12:31 PM

Well sounds like you botched up real bad.

Heres a possable solution, although as FiberOptics has corectly said, there maybe a far better solution, if u can explain what your doing and why.

I thought id give it a go to see if i could think something up. I came up with this.

Anyway, locate your /HMAKE /HADD & /HDEL commands and replace with /_HMAKE /_HADD & /_HDEL, they run the regular command then extra code.

alias _hmake {
  hmake $1-
  if (-* iswm $1) { tokenize 32 $2- }
  var %win = $+(@hw.,$1) | if ($window(%win)) { window -c %win }
alias _hadd {
  hadd $1-
  if (-* iswm $1) { tokenize 32 $2- }
  var %win = $+(@hw.,$1) | if (!$window(%win)) { window -hn %win }
  aline -n %win $2
alias _hdel {
  hdel $1-
  if (-* iswm $1) { tokenize 32 $2- }
  if (!$hget($1)) { return }
  var %win = $+(@hw.,$1) | if (!$window(%win)) { return }
  var %i = 1
  while ($fline(%win,$2,%i)) { if ($line(%win,$v1) == $2) { break } | inc %i }
  if (($fline(%win,$2,%i)) || ($line(%win,$v1) == $2)) { dline %win $fline(%win,$2,%i) }
;usage $_hash(name,N) results with the Nth added item to that table
alias _hash {
  if (($0 >= 2) && ($hget($1)) && ($2 isnum 1-)) {
    var %win = $+(@hw.,$1) | if (!$window(%win)) { return }
    var %c = $int($2)
    var %m = $line(%win,0)
    var %i = 1
    while ((%i <= %c) && (%i <= %m)) {
      if (!$hfind($1,$line(%win,%i))) { dline %win %i | dec %m } | else { inc %i }
    if (%c <= %m) { return $line(%win,%c) }

You can use $_hash(Tablename,N) to locate the Nth added item name, this ONLY works on tables you have used the /_HMAKE /_HADD & /_HDEL commands on

Whats it doing extra?
/_hmake : since this only occurs if the table is new it closes any old hidden window for the table
/_hadd : creates a hidden window for the table if it dont already exist, and adds the new item name if it doesnt exist
/_hdel : if the table exists and the hidden window exists then it searches it for the deleted item and removes said item
$_hash : reads down the hidden window removing non existent items, and returns item N

* Items might become non existent becuase u used /hdel or they were destroyed due to a -uN or a -z flag on the /_hadd
* This means the /_hdel isnt stricklty needed, however if you went /hdel name item and then /_hadd name item it would get left wheer it had been on the creation listand not placed at the end.

Hope this helps. Im sure its not full proof. And doesnt take into account things like /Hinc or /Hdec or /Hload etc.
Posted By: qwerty

Re: HowDo Hash Tables Sort - 11/12/05 05:42 PM

Just curious, what is the red part for?
  if (($fline(%win,$2,%i)) [color:red]|| ($line(%win,$v1) == $2)[/color]) { dline %win $fline(%win,$2,%i) }

- if ($fline()) is true, it means you found the item, so you can delete it right away.

- if ($fline()) is false, it means /break wasn't executed in the above line, so the item was either not found or it wasn't equal to $2 (it contained wildcards that fooled $fline).

So it seems this is enough:
  if ($fline(%win,$2,%i)) { dline %win $v1 }

In fact, the red part may even error, if $2 happens to be the total number of lines in %win: $v1 will be 0, so $line(%win,$v1) will be $line(%win,0), therefore equal to $2, so the condition succeeds.

Unless you meant && instead of ||, which is just redundant (for the same reasons), or I'm just too tired to see it right.
Posted By: DaveC

Re: HowDo Hash Tables Sort - 12/12/05 12:14 AM

Your correct it was ment to be &&, i didnt take the time to think much about it so even if i had got the && right you would have still have found the reduntent bit after it frown
See i copied the WHILE line above and converted it to a final IF check, its the same code just using IF and || (should have been &&)

The code is in fact completely redundant, I should have just included it before the break.

while ($fline(%win,$2,%i)) { if ($line(%win,$v1) == $2) { break } | inc %i }
if (($fline(%win,$2,%i)) || ($line(%win,$v1) == $2)) { dline %win $fline(%win,$2,%i) }

while ($fline(%win,$2,%i)) { if ($line(%win,$v1) == $2) { dline %win $fline(%win,$2,%i) | break } | inc %i }

Damn good spotting by the way!
© 2020 mIRC Discussion Forums