Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUSHclient ➜ General ➜ New feature - array handling for scripting

New feature - array handling for scripting

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1  2 

Posted by Shadowfyr   USA  (1,791 posts)  Bio
Date Reply #15 on Wed 17 Mar 2004 11:00 PM (UTC)
Message
Hmm. Yeah, discounting the activex dictionary object, I guess for the default script types it is useful.

I can see how with some tricks you can create a FIFO, reverse stack or stack, but I am slightly unclear about two factors.

1. If you delete all elements in the array, does it destory the array or set an Empty property of some sort?

I suspect ArraySize returns 0 for an empty which is OK, but see the following...

2. Are the arrays accessable by normal numeric indexes? I.e.:

ArraySet "MyArray", "1", "Fred"

retrieves with:

ArrayGet ("MyArray", "1")
ArrayGet ("MyArray", 1)

Or is the second case disallowed. Even nastier, if the array index is an integer, then it will sort by that and the first index, if 0 or 1 may not even exist as a key. For a FIFO type setup you need to be able to find the *first* element, regardless of what its key is. In other cases, like stacks you can use the ArraySize to find the last element and push the next highest number as the key or retrieve and delete the current one. However, there may still be cases where exporting the array to a string is not the best way to find the first item in the list. Some way to index into the array without the key is needed and in fact is available for Perl and other languages that use such indexed arrays.
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #16 on Thu 18 Mar 2004 01:23 AM (UTC)

Amended on Thu 18 Mar 2004 01:25 AM (UTC) by Nick Gammon

Message
If you delete all elements (ArrayClear) it merely removes the items, thus giving you an empty array whose size is zero.

To delete the array itself you would use ArrayDelete.

Yes, you can use the numbers without quoting them (at least, in VBscript) because of the type casting provided by the script engine. eg.


ArraySet "a", 1, "fish"
ArraySet "a", 20, "chips"
ArraySet "a", 100, "hamburgers"
world.Debug "arrays"
Note ArrayGet ("a", 1)

a
  1 = fish
  20 = chips
  100 = hamburgers
1 array.
fish



This example uses the new techniques recently applied of sorting into numerical order if possible, and as you can see when the array is listed the keys are sorted correctly. Also, I could set and access using pure numeric keys.

As for the first and last item - I hadn't really intended this to be used as a queue or stack, but - what the heck - why not?

I have added two new functions ArrayGetFirstKey and ArrayGetLastKey - these will return the *key* of the first and last elements respectively, regardless of what it might be.

In conjunction with numeric keys, you can now implement a vector (simple list), stack or queue, by simply fiddling with the numbers at either end.

For example, to add to a stack:


i = CInt (ArrayGetLastKey ("mystack"))
ArraySet "mystack", i + 1, "new value"


Similarly you get add to a queue by getting the first key and subtracting 1.

By the same general method you can retrieve the first and last element (first get its key, then use that to get its value), and then if required delete that element.

To index into the array without knowing the keys is what the function ArrayListKeys is for. That returns a variant array (VB array) with each key as an element. You can then use "for each" in VBscript to iterate through the entire array.

However if you are using numeric keys, and not leaving gaps, simply finding the first and last key would be sufficient to know what range to retrieve the elements from.



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #17 on Thu 18 Mar 2004 05:29 AM (UTC)
Message
OK, thanks to everyone who responded. I have now amended the behaviour a bit. In addition to the new routines ArrayGetFirstKey and ArrayGetLastKey, the general behaviour has been changed as follows:


  • There are now *no* checks or changes made to array names, key names or key data. In other words, an array or key can be an empty string, or contain leading and/or trailing spaces. The idea here is that arrays are for use by scripters. If you want to remove spaces, do it yourself.

  • The import/export functions now "escape" out the delimiter itself (if present) so that you can use the delimiter inside the data. I think this is better than having a script that works 99% of the time, but fails one day because someone happens to put a comma into a spell name or something. The escaping is done by putting a backslash in front of it. Because of this backslashes themselves are now escaped as a double-backslash.



One useful side effect of "unnamed" arrays could be that you would use an array with no name as a work array, rather than having to invent a name for it.

The escaping of exported data means you can now nest exported arrays within each other, without having to go mad trying to choose delimiters that won't clash with each other.



- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Dubthach   (47 posts)  Bio
Date Reply #18 on Thu 18 Mar 2004 04:57 PM (UTC)
Message
You are right in saying that JScript does not have associative arrays. We have a custom object for them where I work and we use it constantly. Good addition imho, Nick.
Top

Posted by Dubthach   (47 posts)  Bio
Date Reply #19 on Thu 18 Mar 2004 05:04 PM (UTC)
Message
Some comments:

* I don't think you should allow empty keys.
* You should guarantee that keys are unique, so it can be used to uniquify a list of things. (do this in perl a lot)
* You should provide a way to get the list of values.
Top

Posted by Shadowfyr   USA  (1,791 posts)  Bio
Date Reply #20 on Thu 18 Mar 2004 06:44 PM (UTC)
Message
> * I don't think you should allow empty keys.
If all of them are blank, then does it act list a normal array? If you use two seperate ArraySet commands with non-unique keys, does this produce two entries or replace the first one with the second? This is even more confusing if you get the key array so you can use 'For Each' to step through the contents. Since you cannot retrieve an array of values, you will end up *retrieving* the first value over and over, since all of them are blank, I would assume....? I agree, this is a bad idea.

> * You should guarantee that keys are unique, so it can be used to uniquify a list of things. (do this in perl a lot)

Same issue as question two above. I agree that as long as you depend on ArrayExport or the keys to get the data from the array, allowing non-unique keys is a bad idea. But even if you could get an array of values, if you intentionally want to replace the value of a unique key, how do you do that?? Delete it first, then ArraySet it again I guess, but then how the heck do you replace the value of any single non-unique key? If you try to delete the key, you delete everything or only the first key found with that value, neither one of which is useful.

> * You should provide a way to get the list of values.
Definitely, this would make some things quite a bit easier.

My own suggestion.. Either:

1) a flag you can set on the array that determines its behavior.

2) or a different command, so you can create 'more or less' keyless arrays.

Flag version -

ArrayType "MyArray", "Indexed"
ArraySet "MyArray","Fred","123" 'Works.
ArraySet "MyArray",,"123" 'Generates an error.
ArraySet "MyArray",5,"345" 'Replaces element 5 with "345" or adds element 5 if it doesn't yet exist.

ArrayType "MyArray", "AutoIndex"
ArraySet "MyArray","Fred","123" 'Generates an error.
ArraySet "MyArray",,"123" 'Adds the next highest integer key.
ArraySet "MyArray",5,"345" 'Replaces element 5 with "345", only if element 5 exists. or produces an error if not.

If you used a different command:

ArrayAutoSet "MyArray", "345"

However this would cause confusion if the user mixed them up.

Both options would solve the issue of blank keys, since the key will always be unique and can never be blank. The array would simply act as though it was a normal array with a normal index.

I think the first version with the flag is more usable. Only issue with this is whether to generate an error, or make ArraySet into a function, so it will return True for success and False when it fails. An error is more visible, but a function is slightly more friendly, especially since you probably can't use 'On Error' to trap Mushclient generated errors.
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #21 on Thu 18 Mar 2004 08:42 PM (UTC)

Amended on Thu 18 Mar 2004 08:43 PM (UTC) by Nick Gammon

Message
Quote:

* I don't think you should allow empty keys.


You haven't commented now on whether the keys should be trimmed of leading/trailing spaces.

I know I put in the restriction about keys not being empty, and then took it out, but what is the great harm? A value can be empty, eg.


ArraySet "myarray", "mykey", ""


Now you wouldn't want a restriction that you can't have empty values (because a 'message' or something might be empty). So what is the problem with a blank key? eg.


ArraySet "myarray", "", "some un-named value"


This is being done in a script, if you don't want to use un-named keys (or un-named arrays), don't.

As for the spaces issue, I thought I may as well remove the space trimming, after all, again you can do it if you want to, eg. now these are all different keys:


ArraySet "myarray", "mykey", "foo"
ArraySet "myarray", " mykey", "foo"
ArraySet "myarray", "mykey ", "foo"
ArraySet "myarray", " mykey ", "foo"


Again, this is done in a program (script), if you add an extra space when writing keys, it is no real difference to mistyping the key altogether.

Quote:

* You should guarantee that keys are unique, so it can be used to uniquify a list of things. (do this in perl a lot)


I may not have clarified that. Keys are indeed unique, so if you use any key (including the "empty" key) it will always only refer to a single entry in the array.

The ArraySet function replaces an existing value if necessary, however it returns a different return code if you are keen to know whether that actually happened.

Quote:

* You should provide a way to get the list of values.


You can get an array of the key names, just "for each" through that to extract the values.

However to keep my script-writers happy, I have added a new function ArrayGetValues that simply returns an array of all the values, in case you want them and don't particularly care what the keys are.


Quote:

... or a different command, so you can create 'more or less' keyless arrays.


I don't really see why you would use a keyed array system and then want to make keyless arrays, but in case you do, my earlier suggestion of numeric keys would work. Either keep track of the highest key and just keep adding 1 to it, or use ArrayGetLastKey to find the value of the last key, and add 1 to that, as in my earlier example.


- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Shadowfyr   USA  (1,791 posts)  Bio
Date Reply #22 on Thu 18 Mar 2004 10:21 PM (UTC)

Amended on Thu 18 Mar 2004 10:26 PM (UTC) by Shadowfyr

Message
Ok. That clears things up. So an empty key would be one and only 'one' value in that array, not several. It seemed a bit odd, since I assumed that may mean that keys where not always unique, which is why I suggested an alternate way to generate an array that was indexed, but would appear from the users point of view to not have any. Since the blank key is as unique as any others, this becomes irrelevant.
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #23 on Fri 19 Mar 2004 02:10 AM (UTC)
Message
See Plugin to gag players using new array script routines for a real-life example of using the new routines. The adding/deleting of gagged players is somewhat simplified by being able to key into the array.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


80,395 views.

This is page 2, subject is 2 pages long:  [Previous page]  1  2 

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.