AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

AHKList -- Mutable Lists for AHK

 
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
philz



Joined: 05 Jun 2007
Posts: 89
Location: USA

PostPosted: Mon Jul 21, 2008 1:28 am    Post subject: AHKList -- Mutable Lists for AHK Reply with quote

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 Tue Nov 03, 2009 3:14 pm; edited 2 times in total
Back to top
View user's profile Send private message Send e-mail
Guest






PostPosted: Tue Jul 22, 2008 9:39 am    Post subject: Reply with quote

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. Wink
Back to top
philz



Joined: 05 Jun 2007
Posts: 89
Location: USA

PostPosted: Sat Jul 26, 2008 8:24 pm    Post subject: Reply with quote

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
Back to top
View user's profile Send private message Send e-mail
philz



Joined: 05 Jun 2007
Posts: 89
Location: USA

PostPosted: Mon Mar 02, 2009 6:16 am    Post subject: Reply with quote

The code has been updated to Version 2.
See the original Post

Now the function is actually useful
Back to top
View user's profile Send private message Send e-mail
interested
Guest





PostPosted: Tue Jul 07, 2009 1:07 am    Post subject: Re: AHKList -- Mutable Lists for AHK Reply with quote

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
Back to top
philz



Joined: 05 Jun 2007
Posts: 89
Location: USA

PostPosted: Tue Nov 03, 2009 3:28 pm    Post subject: Sorry about the inconvinience Reply with quote

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.
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group