AutoHotkey Community

It is currently May 26th, 2012, 7:55 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 6 posts ] 
Author Message
PostPosted: July 21st, 2008, 2:28 am 
Offline

Joined: June 5th, 2007, 10:57 pm
Posts: 89
Location: USA
Thanks to the newly supported assume static this feature is actually useful.

This requires Autohotkey version 1.0.48.00 or newer.


Description
The whole idea about this is to create something similar to olegbl's AHKArray without having to deal with all that hexing and delimiters and such. To give programmers a bit of abstraction it stores all items within the local scope of the AHKList function as normal autohotkey arrays (dynamically named variables).

While this could possibly create many variables in the local scope of the AHKList function. Once an item is removed from the list all items after the one deleted are moved forward and the last variable is set blank to save memory.

The programmer may access lists he creates by using a set of commands to the AHKList function. Currently Accepted commands are:
  • Add
  • InsertBefore
  • Get
  • GetIndex
  • Remove
  • Print
  • Pop
  • RemItem
  • WhatsInside
  • Set


Documentation
A more detailed documentation can be found here:
http://philzerull.com/#AHKList


I plan on adding new features as time goes on.
I think a sorting feature will be nice. But please let me know what else might be useful to add to it.

Code
Code:
AHKList(listname, command="add", subcommand1="", subcommand2="", Debug="1") {
    static
    returnit := 1
    if (command = "add") {
        %listname%0 ++
        Curcount := %Listname%0
        %listname%%Curcount% := Subcommand1
        returnit := curcount
    }

    else if (command = "InsertBefore") {
        if (subcommand2 = "") {
            if (Debug)
                Msgbox Error with command: %Command%`nSubcommand2 is Blank
            returnit := 0
        }
        if (returnit) { ;preform only if no error has occured thusfar
            Curcount := %Listname%0
            if (Subcommand2 > Curcount) {
                if (Debug)
                      Msgbox Error with command: %Command%`n%listname% index: Subcommand2 out of range.`nThe index you specified is %Subcommand2%.`nIt should be no larger than %Curcount%.
                returnit := 0
            }
          if (Subcommand2 <= 0) {
              if (Debug)
                Msgbox Error with command: %Command%`n%listname% index: Subcommand2 out of range.`nThe index you specified is 0.`nIt should be at least 1.
              returnit := 0
          }
          if (returnit) { ;preform only if no error has occured thusfar
              loop % Curcount - Subcommand2 + 2 {
                moveto := curcount - (a_index - 1) + 1
                movefrom := curcount - (a_index - 1)
                %Listname%%moveto% := %Listname%%movefrom%
              }
              %listname%0 ++
              %Listname%%moveto% := Subcommand1
              returnit := %listname%0
          }
       }
   }

   else if (command = "Get") {
      curcount := %listname%0
      returnit = 1
      if (Subcommand1="")
         Subcommand1 = 0
      if (subcommand1 < 0) {
         if (debug)
            msgbox Error with command: %Command%`nSubcommand1 must be greater'nthan or equal to zero.
         returnit := 0
      }
       if (Subcommand1 > Curcount) {
         if (Debug)
            Msgbox Error with command: %Command%`n%listname% index: Subcommand1 out of range.`nThe index you specified is %Subcommand1%.`nIt should be no larger than %Curcount%.
         returnit := 0
       }
       if (returnit)
         returnit := %listname%%Subcommand1%
     }

   else if (command = "GetIndex") {
       loop % %listname%0 {
         if (Subcommand1 = %listname%%A_index%) {
            returnit := A_index
            break
         }
         else {
            returnit := 0
         }
         }
         if (debug) AND !(returnit)
         Msgbox Error with command: %Command%`n%Subcommand1% does not exist within %listname%
      }

   else if (command = "Remove") {
       curcount := %listname%0
       if (subcommand1 = "") {
         if (debug)
            Msgbox Error with command: %Command%`nSubcommand1 is expected but missing.
         returnit := 0
       }
      if (subcommand1 < 0) {
         if (debug)
            msgbox Error with command: %Command%`nSubcommand1 must be greater`nthan or equal to zero.
         returnit := 0
      }
       if (returnit) AND ((subcommand1 > curcount) OR !(subcommand1)) {
         if (debug)
            Msgbox Error with command: %Command%`nSubcommand1 is out of range.`nThe value you specified is %subcommand1%.`nIt should be between 1 and %curcount%.
         returnit := 0
       }
       if (returnit) {
         loop % %listname%0 - subcommand1 {
            moveto := subcommand1 + (a_index - 1)
            movefrom := subcommand1 + (a_index - 1) + 1
            %Listname%%moveto% := %Listname%%movefrom%
         }
         AHKList(listname, "Set", %listname%0)
         %listname%0 --
         ;I chose not to blank out the old last index because if I could declare static like i do
         ;global then the user could not access the old last index anyway.
      }
   }
 
   else if (command = "Print") {
      returnit := ""
      loop % %listname%0 {
         returnit = % returnit A_index " " %Listname%%a_index% "`n"
      }
      if (debug)
         msgbox %returnit%
   }
 
   else if (command = "Pop") {
      dummy := AHKList(listname, "Get", AHKList(listname, "Get"))
      AHKList(listname, "Remove", AHKList(listname, "Get"))
      returnit := dummy
   }
   
   else if (command = "RemItem") {
      if (subcommand1 = "") {
            if (debug)
               Msgbox Error with command: %Command%`nSubcommand1 is expected but missing.
            returnit := 0
      }
      if (returnit) {
         dummy := subcommand2 = "" ? 1 : subcommand2
         if (dummy < 0 ) {
            dummy = 0
            loop % AHKList(listname, "get") {
               if (AHKList(listname, "get", a_index + dummy) = subcommand1) {
                  AHKList(listname, "remove", a_index + dummy)
                  dummy --
               }
            }
         }
         else {
            loop % AHKList(listname, "get") {
               if (dummy = 0)
                  break
               if (AHKList(listname, "get", a_index - dummy <= 0 ? 1 : a_index - dummy) = subcommand1) {
                  AHKList(listname, "remove",  a_index - dummy <= 0 ? 1 : a_index - dummy)
                  dummy --
               }
            }
         }
      }
   }
   
   else if (command = "whatsinside") {
      listvars
      msgbox Close this to continue the script
   }
   
   else if (command = "set") {
      if (Subcommand1="")
         Subcommand1 = 0
      else if (subcommand1 < 0) {
         if (debug)
            msgbox Error with command: %Command%`nSubcommand1 must be greater'nthan or equal to zero.
         returnit := 0
      }
       else if (Subcommand1 > Curcount) {
         if (Debug)
            Msgbox Error with command: %Command%`n%listname% index: Subcommand1 out of range.`nThe index you specified is %Subcommand1%.`nIt should be no larger than %Curcount%.
         returnit := 0
       }
      %listname%%Subcommand1% := subcommand2
   }
   return % returnit
}




Examples
Code:

;make a new list called fruit and add a banana to the list

ahklist("Fruit", "add", "Banana")


;to save time typing I'll define a shortcut function
;Please not that ahklist always requires the listname command

fruit(command, subcom1="", subcom2="", debug="1") {
   return % ahklist("Fruit", command, subcom1, subcom2, debug)
}

fruit("add", "Banana")
fruit("add", "Orange")
fruit("add", "Banana")
fruit("add", "Orange")
fruit("add", "Banana")
fruit("add", "Orange")

fruit("add", "Banana")
fruit("add", "Orange")
fruit("add", "Banana")
fruit("add", "Orange")
fruit("add", "Banana")
fruit("add", "Orange")
;Add a whole bunch of fruit to the mix
listvars

msgbox See There are no variables in the global scope
fruit("Whatsinside")
;The variables are all on the local scope

fruit("set", 4, "Mango")
fruit("set", 5)
;Change some values
fruit("print")

fruit("insertbefore", "This is before a mango", 4)
;insert something before the mango.  This puts Mango in the fourth location.
msgbox % fruit("get", 5) "`nSee the " fruit("getindex", "Mango") "th place is a mango."

fruit("remove", 1) ; So i was hungry
; i removed a banana and ate it.

fruit("add", "bubble")
msgbox % "I popped a " fruit("pop")

;Ok so I'll eat the first two bananas

fruit("remitem", "Banana", 2)
fruit("print")
;guess the oranges went bad better get rid of them all.
fruit("remitem", "Orange", -1)

fruit("print")


Please feel free to let me know what you think.
I accept any comments, questions, queries, and qualms.

I am wondering what might be the most user friendly way to store collections of items in AHK.


Last edited by philz on November 3rd, 2009, 4:14 pm, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: July 22nd, 2008, 10:39 am 
I am sure "Mutable Lists" has meaning to many programmers here, but for us dummy AHK users, a description of what it is and how/where it might be used (with examples) would be appreciated.

thanks for a very useful (??) function. ;)


Report this post
Top
  
Reply with quote  
 Post subject:
PostPosted: July 26th, 2008, 9:24 pm 
Offline

Joined: June 5th, 2007, 10:57 pm
Posts: 89
Location: USA
although I have had no formal training and may be incorrect. (please feel free to correct me on this). To explain what mutable lists are I will break it down. Mutable means capable of or tending to change in form or quality or nature, and lists are...well lists. So a mutable list is a list that can change.

they are very much like arrays but I like lists because for those of you VBers or Fortran guys out there with lists you don't have to redim or redefine the array every time you want to put another value into it or remove a value from it.

Here are some examples.

Code:
ahklist("Veggies") ; adds a blank value to the lists "Veggies"
ahklist("Veggies", "add", "Banana") ; adds "Banana" to "Veggies"
ahklist("Veggies", "add", "Orange") ; adds "Orange" to "Veggies"
ahklist("Veggies", "add", "Carrot") ; adds "Carrot" to "Veggies"
ahklist("Veggies", "InsertBefore","",1)
; inserts a blank value before the first veggie
ahklist("Veggies", "InsertBefore", "Potato", 2)
; insets "Potato" before the second index of "Veggies"
ahklist("Veggies", "Get") ; gets the count of veggies
ahklist("Veggies","GetIndex","Banana")
; searches the veggies for a banana and returns it's position
msgbox % ahklist("Veggies","get")
ahklist("mVeggiesylist","remove",1)
; removes the first veggie
msgbox % ahklist("Veggies","get")
listvars
msgbox REMEMBER TO EAT YOUR GREENS
return


notice that listvars shows all of those variables you created. well in a perfect world you wouldn't see those. That's why I'm hoping to be able to make variables assume static. AHK is great but we've been going around the whole lack of array issue for a while and this is just another idea in that direction.

Please comment back to correct anything I have said or offer suggestions for what I should do with AHKList


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 2nd, 2009, 7:16 am 
Offline

Joined: June 5th, 2007, 10:57 pm
Posts: 89
Location: USA
The code has been updated to Version 2.
See the original Post

Now the function is actually useful


Report this post
Top
 Profile  
Reply with quote  
PostPosted: July 7th, 2009, 2:07 am 
philz wrote:
A more detailed documentation can be found here:
http://dl.getdropbox.com/u/387766/index.html#[[Autohotkey%20Functions]]%20AHKList

philz, This function looks like it might be just what I need, but that link for detailed documentation gives "Opps 404" - not found. If you still have that documentation, will you please re-upload it. I think you will find that uploading it to autohotkey.net will be more durable. AutoHotkey.net upload and share your scripts online for free


Report this post
Top
  
Reply with quote  
PostPosted: November 3rd, 2009, 4:28 pm 
Offline

Joined: June 5th, 2007, 10:57 pm
Posts: 89
Location: USA
I fixed the link to the documentation. I hope that it is helpful to you. Sorry about the trouble.

On another note, I don't think I say this anywhere else so I'll mention it here. This function makes use of the newly enabled assume static variables feature. then what this function does us uses ahk's dynamicly named variables to store what the ahk documentation calls arrays within the scope of the function. using listvars outside the function won't display any of the variables within. but the great thing is since all the variables within are static, this provides a very elegent way to store sequential data.

best of luck and if you have any more questions feel free to let me know.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 6 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: infogulch, notsoobvious, tomoe_uehara, Xx7 and 12 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group