mIRC Home    About    Download    Register    News    Help

Print Thread
#137302 11/12/05 06:17 AM
Joined: Feb 2004
Posts: 15
O
Pikka bird
OP Offline
Pikka bird
O
Joined: Feb 2004
Posts: 15
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
2nd

ect...

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

HOW CAN I GET HASH TABLES TO SORT IN ORDER THEY WERE ADDED? confused

#137303 11/12/05 09:48 AM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
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).

#137304 11/12/05 10:01 AM
Joined: Feb 2004
Posts: 2,019
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2004
Posts: 2,019
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.


Gone.
#137305 11/12/05 10:56 AM
Joined: Apr 2003
Posts: 701
K
Hoopy frood
Offline
Hoopy frood
K
Joined: Apr 2003
Posts: 701
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.

#137306 11/12/05 12:31 PM
Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
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.

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.

#137307 11/12/05 05:42 PM
Joined: Jan 2003
Posts: 2,523
Q
Hoopy frood
Offline
Hoopy frood
Q
Joined: Jan 2003
Posts: 2,523
Just curious, what is the red part for?
Code:
  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:
Code:
  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.


/.timerQ 1 0 echo /.timerQ 1 0 $timer(Q).com
#137308 12/12/05 12:14 AM
Joined: Sep 2003
Posts: 4,230
D
Hoopy frood
Offline
Hoopy frood
D
Joined: Sep 2003
Posts: 4,230
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.

taking...
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) }

to...
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!


Link Copied to Clipboard