mIRC Homepage
Posted By: OrionsBelt Replacing tokens in hash tables - 23/04/07 05:54 PM
Hello All,

I have a hash table, with around 1000 items.
Each item has a data line, in the following format:

token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) token5 $chr(9) token6 $chr(9)

Now I need to loop trough the table quite often, and replace a certain token, with a new word.

So:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) Apple $chr(9) token6 $chr(9)
Becomes:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) Melon $chr(9) token6 $chr(9)

Now, I use this code for that:
Code:
    var %cnt = 1
    var %ttl = $hget(table,0).item
    while (%cnt <= %ttl) {
      var %id = %cnt
      var %old-string = $hget(table,%id)
      var %old-token = $gettok(%old-string,5,9))
      var %new-token = Melon
      var %new-string = $puttok(%old-string,%new-token,5,9)

      hdel table %id
      hadd table %id %new-string
      inc %cnt
    }


Is this the most efficient way of doing this?
I've noticed, that when this replacement has to be done like 20 times, it doesn't run very smoothly, and it seems to 'forget' replace some...

Does anyone have suggestions for this?

Thanks a lot!
Posted By: RusselB Re: Replacing tokens in hash tables - 23/04/07 06:13 PM
Code:
var %cnt = 1, %ttl = $hget(table,0).item
while %cnt <= %ttl {
  var %item = $hget(table,%cnt).item, %data = $hget(table,%cnt).data
  .hadd -m table %item $reptokcs(%data,$gettok(%data,5,9),Melon,1,9)
  inc %cnt
}


Note: Some of the items in the code are fixed, per your example, if you need something that is more flexible, you can try to work it out yourself and/or post back here and I'll do it up for you tonight.
Additionally, the above code is case sensitive, if you don't want that, remove the cs from $reptokcs

/help $reptok
Posted By: qwerty Re: Replacing tokens in hash tables - 23/04/07 06:22 PM
First of all, the reason it forgets to replace certain items is probably that $hget(table,%id) does not do what you think: $hget(table,3) does not return the data of the 3rd item, it returns the data of the item named "3". Compare with $hget(table,3).item (and $hget(table,3).data). So unless all your items names are consecutive numbers from 1 to $hget(table,0).item, things will go wrong.

You could first get the item name from the index with something like
var %name = $hget(table,%id).item
and change $hget(%table,%id) to to $hget(%table,%name) but be aware that this will slow down your script considerably ($hget().item/data is not an efficient way to access a hash table).

Also, not sure if you created all those variables just for testing purposes, but your script would run somewhat faster if you got rid of most of them. Here's what I mean (the following does not address the first problem):
Code:
var %cnt = 1, %ttl = $hget(table,0).item
while %cnt <= %ttl {
  hadd table %cnt $puttok($hget(table,%cnt),Melon,5,9)
  inc %cnt
}
Posted By: qwerty Re: Replacing tokens in hash tables - 23/04/07 06:27 PM
Ah you beat me to it. One thing though: there's no reason to change his $puttok() approach to $reptok()/$gettok(). Apart from the fact that it's unnecessarily longer/slower, it won't work correctly if the word "Apple" is in more than one places in the string (and it looks like OrionsBelt wants position-based substitutions rather than content-based).
Posted By: OrionsBelt Re: Replacing tokens in hash tables - 23/04/07 07:17 PM
Thanks for looking into that guys.

Quote:
So unless all your items names are consecutive numbers from 1 to $hget(table,0).item, things will go wrong.


It is consecutive. When a new item gets added, the %id is created with: var %id = $calc($hget(table,0).item + 1)

I will make the re-write like you proposed.
I made the variables so that its easier to understand whats happening for me, but I want it to be as short as possible.
Posted By: RusselB Re: Replacing tokens in hash tables - 23/04/07 10:51 PM
There were a number of possibilities that I thought of when writing my code. I just did it the way I did to match his example. I did state that if he wanted/needed it to be more flexible, to let me know.

I mean, I was able to think of a script that would allow him to replace the first occurance of Word A with Word B, 2nd occurance with Word C, 3rd occurance with Word D, etc. till Word A no longer is in the string, or until all of the replacement words were used, at which point, the balance could be left well alone, or the replacement words could repeat the sequence.

I didn't get it written up, as I wasn't in a location where I could write it up when I thought of it.
Posted By: OrionsBelt Re: Replacing tokens in hash tables - 24/04/07 05:32 AM
I still cant get this to work crazy

Code:
alias reduce-tok5 {
  var %cnt = 1, %ttl = $hget(table,0).item
  while (%cnt <= %ttl) {
    hadd table %cnt $puttok($hget(table,%cnt),$calc($gettok($hget(table,%cnt),5,9) - 1),5,9)
    inc %cnt
  }
}


The table currently contains 400 items (will slowly go up to about 3000).
Each item contains 13 tokens.
It still seems to skip some items, while running the loop.

I want to deduct token 5, once an hour.
So I call this alias, once every hour.

Does anyone have more idea's ?

Thanks in advance!
Posted By: RusselB Re: Replacing tokens in hash tables - 24/04/07 06:35 AM
Correct me if I'm wrong, but it sounds like you're wanting to remove the 5th token from each data string every hour.
If this is correct, you do realize that eventually it's possible for you to not have 5 items in the string.

Additionally, earlier you were talking about replacement, now you're talking about removal. Please clarify which it is.

If it's removal that you want
Code:
alias reduce-tok5 {
  var %cnt = 1, %ttl = $hget(table,0).item
  while %cnt <= %ttl {
    .hadd -m table %cnt $deltok($hget(table,%cnt).data,5,9)
    inc %cnt
  }
}

Posted By: genius_at_work Re: Replacing tokens in hash tables - 24/04/07 01:52 PM
If you tell us exactly what you are trying to accomplish (rather than using other examples), we can help more efficiently.

To me, it sounds like you want to adjust a count/value (of some sort) every hour. Rather than using tokens, I would probably make a separate hash for that value that uses the same item names as the first hash. This allows you to alter the data directly for each hash item, rather than pulling data out or a string of tokens, changing it, and putting it back in.

-genius_at_work
Posted By: OrionsBelt Re: Replacing tokens in hash tables - 24/04/07 04:53 PM
Ok, I'm sorry if I'm not clear.
The code that I showed should make clear what I mean.
I'm not trying to remove any token.
I'm trying to decrease a number (token 5), every hour with 1.

So:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) 158 $chr(9) token6 $chr(9) token7

Becomes after 1 hour:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) 157 $chr(9) token6 $chr(9) token7

Becomes after 2 hours:
token1 $chr(9) token2 $chr(9) token3 $chr(9) token4 $chr(9) 156 $chr(9) token6 $chr(9) token7

The earlier posted code does that.
The problem is that it seems to skip items. Sometimes it does process all items, and sometimes it just skips some.
The code itself does what it should, it just doesn't run stable.

Should I maybe export all items to a text file, make the modification that I want, and load it back into a hash file?
Posted By: RusselB Re: Replacing tokens in hash tables - 24/04/07 06:44 PM
The only thing I can think of, is that occasionally your variables get the wrong values. Try changing your variable names to something that wouldn't be used in another script.
Code:
alias reduce-tok5 {
  var %reduce-tok5.cnt = 1, %reduce-tok5.ttl = $hget(table,0).item
  while (%reduce-tok5.cnt <= %reduce-tok5.ttl) {
    hadd table %reduce-tok5.cnt $puttok($hget(table,%reduce-tok5.cnt),$calc($gettok($hget(table,%reduce-tok5.cnt),5,9) - 1),5,9)
    inc %reduce-tok5.cnt
  }
}


Try that. If that still has problems, then I'm out of ideas.
Posted By: OrionsBelt Re: Replacing tokens in hash tables - 25/04/07 08:07 PM
Ok, thank you for this.
I've reduced the workload, so instead of reducing that token on all items, it now only reduces the ones that match certain criteria (way less items).

I've also refreshed the hash files.
I dont think all tokens were the same, in each item. This might have something to do with it.

For now it's working fine, lets just see how it goes when the file gets bigger.
Anyway, thank you for now.
© mIRC Discussion Forums