Skip to content

An AutoHotkey (AHK) array class with built-in sorting (sorts ANY value), binary search, and common array methods like forEach, join, and more.

License

Notifications You must be signed in to change notification settings

Nich-Cebolla/AutoHotkey-Container

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AutoHotkey-Container - v1.0.5

The last AutoHotkey (AHK) array class you will ever need.

Table of contents

  1. Introduction
  2. AutoHotkey link
  3. Quick start
    1. Decide which sort type to use
    2. Set the sort type
    3. Set ContainerObj.CallbackValue
    4. Set ContainerObj.CallbackCompare
    5. Use the object - Introduction
    6. Use the object - Sort the container
    7. Use the object - Binary search
    8. Use the object - The Value parameter
    9. Use the object - More on binary search
    10. Quick start summary
  4. Sort type
    1. CONTAINER_SORTTYPE_CB_DATE
    2. CONTAINER_SORTTYPE_CB_DATESTR
    3. CONTAINER_SORTTYPE_CB_NUMBER
    4. CONTAINER_SORTTYPE_CB_STRING
    5. CONTAINER_SORTTYPE_CB_STRINGPTR
    6. CONTAINER_SORTTYPE_DATE
    7. CONTAINER_SORTTYPE_DATESTR
    8. CONTAINER_SORTTYPE_DATEVALUE
    9. CONTAINER_SORTTYPE_MISC
    10. CONTAINER_SORTTYPE_NUMBER
    11. CONTAINER_SORTTYPE_STRING
    12. CONTAINER_SORTTYPE_STRINGPTR
  5. Instantiating a Container
    1. Instantiating a Container - Static methods
    2. Instantiating a Container - Instance methods
    3. Container.Prototype.Copy
    4. Container.Prototype.DeepClone
    5. Container.FromArray
    6. Container.StrSplit
  6. Comparing strings
    1. NlsVersionInfoEx
  7. Comparing numbers
  8. Comparing dates
    1. Container_Date
      1. Using Container_Date with timestamps
      2. Using Container_DateParser with date strings
  9. Custom comparisons
  10. Iterative methods
    1. ThisArg parameter
  11. Class details
    1. Static methods
    2. Static properties
    3. Instance methods - Alphabetized list
    4. Instance methods - Categorized list
      1. Instance methods - Sort methods
      2. Instance methods - Binary search methods
        1. Instance methods - Find methods
        2. Instance methods - Insert methods
        3. Instance methods - Delete methods
        4. Instance methods - Remove methods
        5. Instance methods - Date methods
        6. Instance methods - Instantiation methods
      3. Instance methods - Iterative methods
      4. Instance methods - General methods
    5. Instance properties - Alphabetized list
    6. Instance properties - Categorized list
      1. Instance properties - Dynamic properties
      2. Instance properties - Own properties
  12. Miscellaneous info
    1. Binary search
    2. Parameter hints
  13. Changelog

Introduction

Note that in this documentation an instance of Container is referred to either as "a Container object" or ContainerObj.

class Container extends Array

Container inherits from Array and exposes over 100 additional methods to perform common actions such as sorting and finding values.

The class methods can be divided into three categories:

  1. Methods that sort the values in the container. - sort methods
  2. Methods that require the container to be sorted - binary search methods.
  3. Methods that do not require the container to be sorted - iterative methods and general methods.

Categories 2 and 3 above can be further divided into two subcategories:

  1. Methods that allow the container to have unset indices.
  2. Methods that do not allow the container to have unset indices.

The sorting methods always require all indices to have a value. Use Container.Prototype.Condense to remove unset indices.

AutoHotkey link

Join the discussion on autohotkey.com.

Quick start

This section provides the minimum information needed to work with the class' sorting and binary search methods. You can run the examples in this section from file test\test-readme-examples.ahk.

Decide which sort type to use

Using Container objects' sort and binary search methods requires the property ContainerObj.SortType to be set with a valid integer. Set the sort type by calling Container.Prototype.SetSortType, or any of the static macros (e.g. Container.CbString) or instance macros (e.g. Container.Prototype.ToCbString).

c := Container(
    { Name: "obj1" }
  , { Name: "obj3" }
  , { Name: "obj2" }
  , { Name: "obj5" }
)
c.SetSortType(

If your editor supports jsdoc-style parameter hints, press your keyboard shortcut for parameter hints after the open parenthesis to view detailed information about the sort types. You can also find this information in the code file directly above the method Container.Prototype.SetSortType, or in this readme in section Sort type.

Set the sort type

Finish the method call using the global variable. I would recommend using the global variables instead of hardcoding the values because it is more readable. If your code encounters a var unset error, call Container_SetConstants() before using the variables.

; ... continuing with our example

c.SetSortType(CONTAINER_SORTTYPE_CB_STRING)

Set ContainerObj.CallbackValue

If your container contains references to objects, then you will need to define the callback function that returns the value that will be used for sort and find operations. If your container does not contain references to objects, you can still define a callback to convert the values into something else more useful for sorting (if the values are not inherently sortable).

Skip this step if the values in the container are to be sorted as they are.

In our example above we set the sort type to CONTAINER_SORTTYPE_CB_STRING. The "CB" stands for "callback". The sort types with "CB" in the symbol direct the relevant methods to call the callback to get the sort value of the items in the container.

; ... continuing with our example

c.SetCallbackValue(CallbackValue)

CallbackValue(value) {
    return value.Name
}

Set ContainerObj.CallbackCompare

In most cases your code will need to set property ContainerObj.CallbackCompare. The three exceptions are CONTAINER_SORTTYPE_CB_NUMBER, CONTAINER_SORTTYPE_DATEVALUE, and CONTAINER_SORTTYPE_NUMBER, which compare values using subtraction.

  1. If the values will be compared as strings, call Container.Prototype.SetCompareStringEx. Your code can call it without any parameters if the default values are acceptable. A common flag you might want to use is LINGUISTIC_IGNORECASE, which you can pass as the global variable. If your code encounters a var unset error, call Container_SetConstants() before using the variables.
    ; ... continuing with our example
    
    c.SetCompareStringEx(, LINGUISTIC_IGNORECASE)
  2. If the values will be compared as date strings, call one of Container.Prototype.SetCompareDate, Container.Prototype.SetCompareDateStr, Container.Prototype.SetDateParser, or Container.Prototype.DatePreprocess. See the section Comparing dates for more information.
  3. Define your own function to use custom logic.
  • Parameters:
    1. A value to be compared.
    2. A value to be compared.
  • Returns:
    • A number less than zero to indicate the first parameter is less than the second parameter.
    • Zero to indicate the two parameters are equal.
    • A number greater than zero to indicate the first parameter is greater than the second parameter.
  • Example:

Use the object - Introduction

At the top of the description of most instance methods is a line that says "Requires a sorted container: yes/no" and a line that says "Allows unset indices: yes/no".

Methods that require a sorted container are methods that implement a binary search. A binary search is when you split a range in half repeatedly to narrow in on an input value.

Most methods that do not require a sorted container are methods that iterate over items in the container sequentially. These are adapted from javascript array methods.

Methods that allow unset indices are designed to check whether an index has a value before performing the action on that index. These methods typically have the word "Sparse" at the end of the method name, e.g. Container.Prototype.FindSparse.

Use the object - Sort the container

There are three sort methods available:

  • Container.Prototype.InsertionSort - Sorts in-place and is appropriate for small containers (n <= 32).
    c.InsertionSort()
  • Container.Prototype.Sort - Sorts in-place (heap sort) and is appropriate for all containers.
    c.Sort()
  • Container.Prototype.QuickSort - Does not mutate the original container (returns a new container) and is about 30% faster than Container.Prototype.Sort, but uses up to 10x the memory. I recommend using Container.Prototype.QuickSort in any case where sorting in-place is not necessary and where memory is not an issue. You can return the value to the same variable; the returned container will have any own properties from the original, including properties added by external code, and will have the same base as the original:
    c := c.QuickSort()

Use the object - Binary search

Binary search requires a sorted container. There are over twenty binary search methods available, including actions such as finding, deleting, and inserting values in order. They all rely on the various "Find" methods. The following is a brief description of the "Find" methods available:

  • Find : Finds a value and returns the index.
  • FindAll : Finds a value and returns the first index with the value and has a VarRef parameter that will receive the last index with the value.
  • FindInequality : Finds the first value that is >, >=, <, or <= the input value, and returns the index.

Container also has a sparse version of each of the above.

Understand that, if your code will be using the binary search methods, the container must stay sorted. Your code should not add values to the container with Array.Prototype.Push or Container.Prototype.PushEx. Instead, use any of the "Insert" methods to insert values in order.

To find the index where a value is located, use the "Find" methods. Continuing with our earlier example...

index := c.Find("obj1")
OutputDebug(index "`n") ; 1
index := c.Find("obj4")
OutputDebug(index "`n") ; 0
index := c.Find(c[3])
OutputDebug(index "`n") ; 3

To get a value as a return value, use "GetValue" or "GetValueSparse".

if ObjPtr(c.GetValue("obj2")) == ObjPtr(c[2]) {
    OutputDebug("obj2 is in the correct position.`n")
}

To insert a value in order, use one of the "Insert" methods.

c.Insert({ Name: "obj4" })
index := c.Find("obj4")
OutputDebug(index "`n") ; 4

To delete a value and leave an unset index, use one of the "DeleteValue" methods.

index := c.DeleteValue("obj4")
OutputDebug(index "`n") ; 4
OutputDebug(c.Has(4) "`n") ; 0

To remove a value and shift values to the left to fill in the space, use one of the "Remove" methods.

index := c.Remove("obj3")
OutputDebug(index "`n") ; 3
; The empty index from deleting "obj4" is now at index 3
OutputDebug(c.Has(3) "`n") ; 0
; "obj5" is now at index 4
OutputDebug(c[4].Name "`n") ; obj5

Use the object - The Value parameter

You will notice that the first parameter of any method that implements a binary search is Value - the value to find.

The type of value that is valid to pass to Value depends on the sort type, but can be appropriately summarized as:

  • If ContainerObj.CallbackValue has been set, Value can be an object as long as the CallbackValue function can be used to return the sort value.
  • Value can also be a primitive value as long as the value is valid for the sort type.

Each of the following are valid using our example container:

val := "obj1"
c.Find(val)
val := { Name: "obj1" }
c.Find(val)
val := c[1]
c.Find(val)

Date values behave somewhat differently because there are two kinds of date strings that can be recognized by Container - standard yyyyMMddHHmmss strings, and also strings that will be passed to an instance of Container_DateParser. Furthermore, Container.Prototype.DatePreprocess converts date strings to a number, expanding the permissible kinds of values to include integers repesenting date values (number of seconds since Jan 01, 1, 00:00:00).

See Comparing dates for more information.

Here is a comprehensive list:

  • CONTAINER_SORTTYPE_CB_DATE:
    • Object : A value that, when passed to ContainerObj.CallbackValue, returns a yyyyMMddHHmmss string or integer.
    • Primitive : A yyyyMMddHHmmss string or integer.
  • CONTAINER_SORTTYPE_CB_DATESTR:
    • Object : A value that, when passed to ContainerObj.CallbackValue, returns a date string that can be parsed by ContainerObj.DateParser.
    • Primitive : A yyyyMMddHHmmss string or integer.
    • Primitive : A date string that can be parsed by ContainerObj.DateParser.
  • CONTAINER_SORTTYPE_CB_NUMBER:
    • Object : A value that, when passed to ContainerObj.CallbackValue, returns a number or numeric string.
    • Primitive : A number or numeric string.
  • CONTAINER_SORTTYPE_CB_STRING:
    • Object : A value that, when passed to ContainerObj.CallbackValue, returns a string.
    • Primitive : An integer representing the ptr to a null-terminated string.
    • Primitive : A string value.
  • CONTAINER_SORTTYPE_CB_STRINGPTR:
    • Object : A value that, when passed to ContainerObj.CallbackValue, returns an integer representing the ptr to a null-terminated string.
    • Primitive : An integer representing the ptr to a null-terminated string.
    • Primitive : A string value.
  • CONTAINER_SORTTYPE_DATE:
    • Primitive : A yyyyMMddHHmmss string or integer.
  • CONTAINER_SORTTYPE_DATESTR:
    • Primitive : A yyyyMMddHHmmss string or integer.
    • Primitive : A date string that can be parsed by ContainerObj.DateParser.
  • CONTAINER_SORTTYPE_DATEVALUE:
    • Object : A value that, when passed to ContainerObj.CallbackValue, returns a date string that can be parsed by ContainerObj.DateParser.
    • Object : A value that was an item in the container when Container.Prototype.DatePreprocess or Container.Prototype.DateUpdate was called, and that still has the property set with the date value as integer.
    • Primitive : A date string that can be parsed by ContainerObj.DateParser.
    • Primitive : An integer representing the number of seconds between Jan 01, 1, 00:00:00 and the date.
  • CONTAINER_SORTTYPE_MISC:
    • Object or primitive : Any value that can be passed to ContainerObj.CallbackCompare.
  • CONTAINER_SORTTYPE_NUMBER:
    • Primitive : A number.
  • CONTAINER_SORTTYPE_STRING:
    • Primitive : An integer representing the ptr to a null-terminated string.
    • Primitive : A string value.
  • CONTAINER_SORTTYPE_STRINGPTR:
    • Primitive : An integer representing the ptr to a null-terminated string.
    • Primitive : A string value.

Use the object - More on binary search

Internally, AutoHotkey's Map class and object property tables implement a binary search. This allows us to associate values with string names.

Though Map is sufficient for many cases, I often found myself wanting the best of both worlds - I want to be able to refer to an item by name, and I also want to be able to refer to an item by index and use operations that are dependent on the values being serialized. I wrote Container for this use case.

Our example container is already set up to be used this way, but let's recreate it for demonstration:

; Items must have a property that can be used as the name / key.
c := Container(
    { Name: "obj1" }
  , { Name: "obj3" }
  , { Name: "obj2" }
  , { Name: "obj5" }
)

; Set the sort type to `CONTAINER_SORTTYPE_CB_STRING`.
c.SetSortType(CONTAINER_SORTTYPE_CB_STRING)

; Set CallbackValue with a function that returns the name / key.
c.SetCallbackValue(CallbackValue)

CallbackValue(value) {
    return value.Name
}

; Call `Container.Prototype.SetCompareStringEx` with / without optional parameters.
c.SetCompareStringEx(, LINGUISTIC_IGNORECASE)

; Sort the container.
c := c.QuickSort()

Using the CONTAINER_SORTTYPE_CB_STRING sort type allows us to define an object property as the source of the name. As long as each object in the container has the same property that returns a string value, then we can use the container in a manner similar to a Map object.

The following is a list of methods that are analagous to Map instance methods.

  • Map.Prototype.Clear -
    • Use ContainerObj.Length := 0.
  • Map.Prototype.Clone -
    • Use Array.Prototype.Clone (i.e. call ContainerObj.Clone()) to include the items in the clone
    • Use Container.Prototype.Copy to only copy the own properties and base object.
    • Use Container.Prototype.DeepClone to deep clone the own properties and items and copy the base object.
  • Map.Prototype.Delete -
    • Use delete or remove methods.
      c.DeleteValue("obj1")
      c.Remove("obj2")
  • Map.Prototype.Get -
    • Use find methods.
      if c.Find("obj3", &value) {
          ; do something, probably with `value`
      }
      obj := c.GetValue("obj1")
  • Map.Prototype.Has -
    • Use find methods.
      if c.Find("obj3") {
          ; do something
      }
  • Map.Prototype.Set -
    • Use insert methods.
      c.Insert({ Name: "obj4" })
      if c.InsertIfAbsent({ Name: "obj1" }) {
          ; do something
      }
  • Map.Prototype.__Enum -
    • Use Container.Prototype.Enum, Container.Prototype.EnumRange, or Container.Prototype.EnumRangeSparse.
      for index, name, obj in c.EnumRange(3, "obj2", "obj4") {
          OutputDebug(index ": " name " - " Type(obj) "`n")
      }

Quick start summary

  • A Container object requires 1-3 properties to be viable for sort and binary search operations.
    • ContainerObj.SortType - An integer representing the sort type.
    • ContainerObj.CallbackCompare - A function which compares two values.
      • For string comparisons, call Container.Prototype.SetCompareStringEx.
      • For date comparisons with yyyyMMddHHmmss strings, call Container.Prototype.SetCompareDate.
      • For date comparisons with date strings, call Container.Prototype.SetCompareDateStr with a format string.
      • Number comparisons do not require a comparator.
    • ContainerObj.CallbackValue - A function that returns the sort value, mostly used with objects to return a property value.
  • To use a Container like a Map object, use sort type CONTAINER_SORTTYPE_CB_STRING.
  • Add values to the container using one of the "Insert" methods to keep the values in order.
  • Methods are divided into sparse and non-sparse versions.
  • Iterative methods do not require any preparation; they can always be called.

Don't forget to leave a ⭐ if you think Container is pretty awesome!

Sort type

This section lists the sort types, which properties they require, and provides an example of each.

    Jump to:
  1. CONTAINER_SORTTYPE_CB_DATE
  2. CONTAINER_SORTTYPE_CB_DATESTR
  3. CONTAINER_SORTTYPE_CB_NUMBER
  4. CONTAINER_SORTTYPE_CB_STRING
  5. CONTAINER_SORTTYPE_CB_STRINGPTR
  6. CONTAINER_SORTTYPE_DATE
  7. CONTAINER_SORTTYPE_DATESTR
  8. CONTAINER_SORTTYPE_DATEVALUE
  9. CONTAINER_SORTTYPE_MISC
  10. CONTAINER_SORTTYPE_NUMBER
  11. CONTAINER_SORTTYPE_STRING
  12. CONTAINER_SORTTYPE_STRINGPTR

CONTAINER_SORTTYPE_CB_DATE

  • CallbackValue: Provided by your code and returns a string in the format yyyyMMddHHmmss.
  • CallbackCompare: Set by calling Container.Prototype.SetCompareDate.
CallbackValue(value) {
    return value.timestamp
}

c := Container(
    { timestamp: "20250312122930" }
  , { timestamp: "20250411122900" }
  , { timestamp: "20251015091805" }
)

c.SetSortType(CONTAINER_SORTTYPE_CB_DATE)
c.SetCallbackValue(CallbackValue)
c.SetCompareDate()
c.Sort()

CONTAINER_SORTTYPE_CB_DATESTR

  • CallbackValue: Provided by your code and returns a date string in any format recognized by the Container_DateParser set to ContainerObj.DateParser.
  • CallbackCompare: Set by calling Container.Prototype.SetCompareDateStr or Container.Prototype.SetDateParser.
CallbackValue(value) {
    return value.date
}

c := Container(
    { date: "2025-03-12 12:29:30" }
  , { date: "2025-04-11 12:29:00" }
  , { date: "2025-10-15 09:18:05" }
)

c.SetSortType(CONTAINER_SORTTYPE_CB_DATESTR)
c.SetCallbackValue(CallbackValue)
c.SetCompareDateStr("yyyy-MM-dd HH:mm:ss")
c.Sort()

CONTAINER_SORTTYPE_CB_NUMBER

  • CallbackValue: Provided by your code and returns a number.
  • CallbackCompare: Not used.
CallbackValue(value) {
    return value.value
}

c := Container(
    { value: 298581 }
  , { value: 195801 }
  , { value: 585929 }
)

c.SetSortType(CONTAINER_SORTTYPE_CB_NUMBER)
c.SetCallbackValue(CallbackValue)
c.Sort()

CONTAINER_SORTTYPE_CB_STRING

  • CallbackValue: Provided by your code and returns a string.
  • CallbackCompare: Set by calling Container.Prototype.SetCompareStringEx.
CallbackValue(value) {
    return value.name
}

c := Container(
    { name: "obj4" }
  , { name: "obj3" }
  , { name: "obj1" }
)

c.SetSortType(CONTAINER_SORTTYPE_CB_STRING)
c.SetCallbackValue(CallbackValue)
c.SetCompareStringEx()
c.Sort()

CONTAINER_SORTTYPE_CB_STRINGPTR

If you know your code will be used for a lot of sorting and finding operations, you can improve performance by storing the name / key in a buffer.

  • CallbackValue: Provided by your code and returns a pointer to a null-terminated string.
  • CallbackCompare: Set by calling Container.Prototype.SetCompareStringEx.
class ImageSamples {
    __New(Name, ImageData) {
        this.NameBuffer := Buffer(StrPut(Name, "cp1200"))
        StrPut(Name, this.NameBuffer, "cp1200")
        this.ImageData := ImageData
    }
    Name => StrGet(this.NameBuffer, "cp1200")
}

CallbackValue(value) {
    return value.NameBuffer.Ptr
}

c := Container(
    ImageSamples("obj4", data4)
  , ImageSamples("obj3", data3)
  , ImageSamples("obj1", data1)
)

c.SetSortType(CONTAINER_SORTTYPE_CB_STRINGPTR)
c.SetCallbackValue(CallbackValue)
c.SetCompareStringEx()
c.Sort()

CONTAINER_SORTTYPE_DATE

  • CallbackValue: Not used. Values in the container are date strings in the format yyyyMMddHHmmss.
  • CallbackCompare: Set by calling Container.Prototype.SetCompareDate.
c := Container(
    "20250312122930"
  , "20250411122900"
  , "20251015091805"
)

c.SetSortType(CONTAINER_SORTTYPE_DATE)
c.SetCompareDate()
c.Sort()

CONTAINER_SORTTYPE_DATESTR

  • CallbackValue: Not used. Values in the container are date strings in any format recognized by the Container_DateParser set to ContainerObj.DateParser.
  • CallbackCompare: Set by calling Container.Prototype.SetCompareDateStr or Container.Prototype.SetDateParser.
c := Container(
    "2025-03-12 12:29:30"
  , "2025-04-11 12:29:00"
  , "2025-10-15 09:18:05"
)

c.SetSortType(CONTAINER_SORTTYPE_DATESTR)
c.SetCompareDateStr("yyyy-MM-dd HH:mm:ss")
c.Sort()

CONTAINER_SORTTYPE_DATEVALUE

Your code does not assign this sort type directly. See the description for Container.Prototype.DatePreprocess for details about this sort type.

CONTAINER_SORTTYPE_MISC

  • CallbackValue: Not used. Values in the container are any kind of value.
  • CallbackCompare: Provided by your code and implements custom logic to return the comparison value.
; Sort words by string length
CallbackCompare(value1, value2) {
    return StrLen(value1) - StrLen(value2)
}

c := Container(
    "cat"
  , "elephant"
  , "kale"
)

c.SetSortType(CONTAINER_SORTTYPE_MISC)
c.SetCallbackCompare(CallbackCompare)

CONTAINER_SORTTYPE_NUMBER

  • CallbackValue: Not used. Values in the container are numbers.
  • CallbackCompare: Not used.
c := Container(
    298581
  , 195801
  , 585929
)

c.SetSortType(CONTAINER_SORTTYPE_NUMBER)
c.Sort()

CONTAINER_SORTTYPE_STRING

  • CallbackValue: Not used. Values in the container are strings.
  • CallbackCompare: Set by calling Container.Prototype.SetCompareStringEx.
c := Container(
    "string4"
  , "string3"
  , "string1"
)

c.SetSortType(CONTAINER_SORTTYPE_STRING)
c.SetCompareStringEx()
c.Sort()

CONTAINER_SORTTYPE_STRINGPTR

  • CallbackValue: Not used. Values in the container are pointers to null-terminated strings.
  • CallbackCompare: Set by calling Container.Prototype.SetCompareStringEx.
StrBuf(str) {
    buf := Buffer(StrPut(str, "cp1200"))
    StrPut(str, buf, "cp1200")
    return buf
}

buf1 := StrBuf("string4")
buf2 := StrBuf("string3")
buf3 := StrBuf("string1")
c := Container(
    buf1.Ptr
  , buf2.Ptr
  , buf3.Ptr
)

c.SetSortType(CONTAINER_SORTTYPE_STRINGPTR)
c.SetCompareStringEx()
c.Sort()

Instantiating a Container

The examples in the Quick start section demonstrate how to prepare a container the long way so you can understand the various components. Typically you will instantiate a container using an alternative method.

Instantiating a Container - Static methods

Use one of the static methods to instantiate a new container with all the needed properties for the specified sort type.

  • Container.CbDate
  • Container.CbDateStr
  • Container.CbDateStrFromParser
  • Container.CbNumber
  • Container.CbString
  • Container.CbStringPtr
  • Container.Date
  • Container.DateStr
  • Container.DateStrFromParser
  • Container.DateValue
  • Container.Misc
  • Container.Number
  • Container.String
  • Container.StringPtr

Instantiating a Container - Instance methods

Use one of the "To<Name>" instance methods to set the needed properties on an existing instance.

  • Container.Prototype.ToCbDate
  • Container.Prototype.ToCbDateStr
  • Container.Prototype.ToCbDateStrFromParser
  • Container.Prototype.ToCbNumber
  • Container.Prototype.ToCbString
  • Container.Prototype.ToCbStringPtr
  • Container.Prototype.ToDate
  • Container.Prototype.ToDateStr
  • Container.Prototype.ToDateStrFromParser
  • Container.Prototype.ToDateValue
  • Container.Prototype.ToMisc
  • Container.Prototype.ToNumber
  • Container.Prototype.ToString
  • Container.Prototype.ToStringPtr

Container.Prototype.Copy

Container.Prototype.Copy allows you to use one Container object to instantiate another identical Container object. Unlike Array.Prototype.Clone which will also copy the items, Container.Prototype.Copy only copies the own properties and the base object to the new instance. If your project will be using a number of Container objects with the same setup, you can simply create a template and then any time your project needs a new instance, copy the template.

Make the template:

template_calldate := Container.DateValue(Container_CallbackValue_Calldate, "yyyy-MM-dd HH:mm:ss")

Container_CallbackValue_Calldate(value) {
    return value.calldate
}

Make a copy:

c := template_calldate.Copy()

Any own properties which were added to template_calldate will be reflected on c, and also if the base of template_calldate was changed then c will have the same base (assuming the base still inherits from Container and does not override Container.Prototype.Copy).

Container.Prototype.Copy does not deep clone property values that are objects. For object property values, the value on the template will be the same object as the one on the new instance.

Container.Prototype.DeepClone

Container.Prototype.DeepClone is adapted from my Object.Prototype.DeepClone. It will deep clone the Container object, its own properties, and its items. The return value is a Container object with the same base, deep cloned own properties, and deep cloned items. It does not deep clone inherited property values that are objects.

Container.FromArray

Container.FromArray takes an existing Array object and converts it to a Container object, returning the original object after changing the base to Container.Prototype.

Container.StrSplit

Container.StrSplit calls AutoHotkey's built-in StrSplit, then sets the base of the array to Container.Prototype, effectively allowing your code to instantiate a Container object using StrSplit.

Comparing strings

Strings are compared using Microsoft's CompareStringEx. When sorting values using string comparison, your code will call Container.Prototype.SetCompareStringEx or one of the instantiation helpers which calls Container.Prototype.SetCompareStringEx.

NlsVersionInfoEx

NlsVersionInfoEx is a class used to create an NLSVERSIONINFOEX structure. This is passed to Container.Prototype.SetCompareStringEx to specify the National Language Support version. For general use cases you can leave the NlsVersionInfo parameter as the default (0). The NLS version is only needed if your code is working with older datasets or libraries that expect a specific version with respect to sort and comparison operations.

Comparing numbers

Numbers are compared with basic subtraction.

CompareNumbers(value1, value2) {
    return value1 - value2
}

Comparing dates

This section details how Container handles yyyyMMddHHmmss timestamps, date strings, and date values.

Much of this information is available in the parameter hints for the relevant methods.

Note that there is no built-in support for dates prior to year 1, nor support for date systems other than the modern proleptic Gregorian calendar.

The methods Container.Prototype.SetCompareDateStr and Container.Prototype.SetDateParser, have a parameter UseCompareDateEx which specifies how date values will be compared. (Note that any of the instantiation helpers that instantiate a Container object with a date-related sort type also exposes UseCompareDateEx).

When UseCompareDateEx is false, date values are compared using AutoHotkey's built-in DateDiff. When a Container_Date object is used, the method Container_Date.Prototype.Diff facilitates this process.

I added UseCompareDateEx to address this limitation of DateDiff - "If DateTime contains an invalid timestamp or a year prior to 1601, a ValueError is thrown. When UseCompareDateEx is true, date strings are compared using a "date value", which is an integer representing the number of seconds between Jan 01, 1, 00:00:00 and the date associated with the Container_Date object. The value is returned by the dynamic property Container_Date.Prototype.TotalSeconds which calls Container_Date.GetSeconds("00010101000000", this.Timestamp). A couple things to note:

  • This process is noticeably slower than DateDiff, but this is mitigated by calling Container.Prototype.DatePreprocess which optimizes date comparisons significantly.
  • Leap years are handled using the following logic which I obtained from Wikipedia.
    • Leap years occur every 4 years (Mod(year, 4) = 0) except years that are divisible by 100 and not divisible by 400 are not leap years.
    • This logic is boiled down to the following function to return the number of leap years prior to an input year:
      static LeapCountBefore(Year) {
          k := Year - 1
          return Floor(k / 4) - Floor(k / 100) + Floor(k / 400)
      }

Container_Date

Container_Date and Container_DateParser are repurposed from my DateObj class. The methods are fully documented in either file, but this section provides a quick rundown.

Using Container_Date with timestamps

Container_Date.FromTimestamp accepts a whole or partial timestamp (yyyyMMddHHmmss) string / integer and returns a Container_Date object. Container_Date.FromTimestamp is used with sort type CONTAINER_SORTTYPE_CB_DATE and CONTAINER_SORTTYPE_DATE when UseCompareDateEx is true.

Using Container_DateParser with date strings

Container_DateParser is a regex-based system for parsing dates from arbitray text. To use it, your code provides a date format string that the parser can use to identify dates in some input text.

c := Container(
    { calldate: "2025-03-01 12:13:01" }
  , { calldate: "2025-03-01 12:24:15" }
  , { calldate: "2025-03-01 12:15:09" }
  , { calldate: "2025-03-01 12:30:30" }
)

c.SetSortType(CONTAINER_SORTTYPE_CB_DATESTR)
; When we call `Container.Prototype.SetCompareDateStr` we include the date format
c.SetCompareDateStr("yyyy-MM-dd HH:mm:ss")
c.SetCallbackValue((value) => value.calldate)
c.Sort()

Follow these guidelines when writing a date format string:

  • The units "y", "M", "d", "H", "h", "m", "s", and "t" each can be used to match with specific values in a date string. See FormatTime for details about the units.
  • Only numeric day units are recognized; names like "Mon", "Tuesday", etc., are not recognized by Container_DateParser.
  • Container_DateParser will match with both numeric month units and month names.
  • In addition to the units, RegEx is viable within the format string. The following restrictions permit compatibility between the unit characters and RegEx:
    • If the format string contains one or more literal "y", "M", "d", "H", "h", "m", "s" or "t" characters, you must escape the date format units using this escape: \t{...}
      • Example without using \t{...}:
        DateStr := "2024-01-28 19:15"
        DateFormat := "yyyy-MM-dd HH:mm"
        Date := Container_Date(DateStr, DateFormat)
        MsgBox(Date.Year "-" Date.Month "-" Date.Day " " Date.Hour ":" Date.Minute) ; 2024-01-28 19:15
      • Example with using \t{...}:
        DateStr := "Voicemail From <1-555-555-5555> at 2024-01-28 07:15:20"
        DateFormat := "at \t{yyyy-MM-dd HH:mm:ss}"
        Date := Container_Date(DateStr, DateFormat)
        MsgBox(Date.Year "-" Date.Month "-" Date.Day " " Date.Hour ":" Date.Minute ":" Date.Second) ; 2024-01-28 07:15:20
    • You can include multiple sets of \t escaped format units.
      DateStr := "Voicemail From <1-555-555-5555> Received January 28, 2024 at 12:15:20 AM"
      DateFormat := "Received \t{MMMM dd, yyyy} at \t{hh:mm:ss tt}"
      ; Use case insensitive matching when matching a month by name.
      Date := Container_Date(DateStr, DateFormat, "i)")
      MsgBox(Date.Year "-" Date.Month "-" Date.Day " " Date.Hour ":" Date.Minute ":" Date.Second) ; 2024-01-28 00:15:20
    • You can use the "?" quantifier.
      DateStr1 := "Voicemail From <1-555-555-5555> Received January 28, 2024 at 12:15 AM"
      DateStr2 := "Voicemail From <1-555-555-5555> Received January 28, 2024 at 12:15:12 AM"
      DateFormat := "Received \t{MMMM dd, yyyy} at \t{hh:mm:?ss? tt}"
      ; Use case insensitive matching when matching a month by name.
      Date1 := Container_Date(DateStr1, DateFormat, "i)")
      Date2 := Container_Date(DateStr2, DateFormat, "i)")
      MsgBox(Date1.Year "-" Date1.Month "-" Date1.Day " " Date1.Hour ":" Date1.Minute ":" Date1.Second) ; 2024-01-28 00:15:00
      Date2 := Container_Date(DateStr2, DateFormat)
      MsgBox(Date2.Year "-" Date2.Month "-" Date2.Day " " Date2.Hour ":" Date2.Minute ":" Date2.Second) ; 2024-01-28 00:15:12
    • The match object is set to the property Container_DateObj.Match. Include any extra subcapture groups that you are interested in.
      DateStr := "The child was born May 2, 1990, the year of the horse"
      DateFormat := "\t{MMMM d, yyyy}, the year of the (?<animal>\w+)"
      ; Use case insensitive matching when matching a month by name.
      Date := Container_Date(DateStr, DateFormat, "i)")
      MsgBox(Date.Year "-" Date.Month "-" Date.Day " " Date.Hour ":" Date.Minute ":" Date.Second) ; 1990-05-02 00:00:00
      MsgBox(Date.Match["animal"]) ; horse

Custom comparisons

The CONTAINER_SORTTYPE_MISC sort type is for custom comparisons. When using CONTAINER_SORTTYPE_MISC, your code only calls Container.Prototype.SetCallbackCompare; it does not call Container.Prototype.SetCallbackValue. When values are compared, the values are passed to ContainerObj.CallbackCompare as-is, and your function is expected to return a number indicating the relationship between the two. See CONTAINER_SORTTYPE_MISC for an example.

Iterative methods

Iterative methods iterate over the values in the container sequentially. Like the other methods, there are sparse and non-sparse versions of each method.

Iterative methods have a parameter Callback. This is separate from the ContainerObj.CallbackValue and ContainerObj.CallbackCompare functions; Callback never gets cached as a property by the iterative methods.

ThisArg parameter

Some of the iterative methods have a parameter ThisArg. See file test\ThisArg-example.ahk for details about using the ThisArg parameter.

Class details

This section lists the class static methods, instance methods, and instance properties. When a property or method is listed as Container.Prototype.<Name>, that property exists on Container.Prototype. When a property or method is listed as ContainerObj.<Name>, that property is an own property that is added to the Container object some time during or after instantiation.

Static methods

The following is a list of static methods.

  • Container.CbDate
  • Container.CbDateStr
  • Container.CbDateStrFromParser
  • Container.CbNumber
  • Container.CbString
  • Container.CbStringPtr
  • Container.Date
  • Container.DateStr
  • Container.DateStrFromParser
  • Container.DateValue
  • Container.FromArray
  • Container.Misc
  • Container.Number
  • Container.String
  • Container.StringPtr
  • Container.StrSplit

Static properties

The following is a list of static properties.

  • Container.SortTypeSymbolList

Instance methods - Alphabetized list

In addition to the methods inherited from Array, Container has the following methods:

  • Container.Prototype.Compare
  • Container.Prototype.Condense
  • Container.Prototype.Copy
  • ContainerObj.DateConvert
  • ContainerObj.DateConvertCb
  • Container.Prototype.DateInsert
  • Container.Prototype.DateInsertIfAbsent
  • Container.Prototype.DateInsertIfAbsentSparse
  • Container.Prototype.DateInsertList
  • Container.Prototype.DateInsertListSparse
  • Container.Prototype.DateInsertSparse
  • Container.Prototype.DatePreprocess
  • Container.Prototype.DateUpdate
  • Container.Prototype.DeepClone
  • Container.Prototype.DeleteAll
  • Container.Prototype.DeleteAllSparse
  • Container.Prototype.DeleteValue
  • Container.Prototype.DeleteValueIf
  • Container.Prototype.DeleteValueIfSparse
  • Container.Prototype.DeleteValueSparse
  • Container.Prototype.Enum
  • Container.Prototype.EnumRange
  • Container.Prototype.EnumRangeSparse
  • Container.Prototype.Every
  • Container.Prototype.EverySparse
  • Container.Prototype.Find
  • Container.Prototype.FindAll
  • Container.Prototype.FindAllSparse
  • Container.Prototype.FindInequality
  • Container.Prototype.FindInequalitySparse
  • Container.Prototype.FindSparse
  • Container.Prototype.Flat
  • Container.Prototype.ForEach
  • Container.Prototype.ForEachSparse
  • Container.Prototype.GetValue
  • Container.Prototype.GetValueSparse
  • Container.Prototype.HasValue
  • Container.Prototype.HasValueSparse
  • Container.Prototype.Insert
  • Container.Prototype.InsertIfAbsent
  • Container.Prototype.InsertIfAbsentSparse
  • Container.Prototype.InsertList
  • Container.Prototype.InsertListSparse
  • Container.Prototype.InsertSparse
  • Container.Prototype.InsertionSort
  • Container.Prototype.Join
  • Container.Prototype.JoinEx
  • Container.Prototype.Map
  • Container.Prototype.MapSparse
  • Container.Prototype.Purge
  • Container.Prototype.PurgeSparse
  • Container.Prototype.PushEx
  • Container.Prototype.QuickSort
  • Container.Prototype.Reduce
  • Container.Prototype.ReduceSparse
  • Container.Prototype.Remove
  • Container.Prototype.RemoveAll
  • Container.Prototype.RemoveAllSparse
  • Container.Prototype.RemoveIf
  • Container.Prototype.RemoveIfSparse
  • Container.Prototype.RemoveSparse
  • Container.Prototype.Reverse
  • Container.Prototype.ReverseSparse
  • Container.Prototype.Search
  • Container.Prototype.SearchAll
  • Container.Prototype.SearchAllSparse
  • Container.Prototype.SearchSparse
  • Container.Prototype.SetCallbackCompare
  • Container.Prototype.SetCallbackValue
  • Container.Prototype.SetCompareStringEx
  • Container.Prototype.SetCompareDate
  • Container.Prototype.SetCompareDateStr
  • Container.Prototype.SetDateParser
  • Container.Prototype.SetSortType
  • Container.Prototype.Slice
  • Container.Prototype.Sort
  • Container.Prototype.ToCbDate
  • Container.Prototype.ToCbDateStr
  • Container.Prototype.ToCbDateStrFromParser
  • Container.Prototype.ToCbNumber
  • Container.Prototype.ToCbString
  • Container.Prototype.ToCbStringPtr
  • Container.Prototype.ToDate
  • Container.Prototype.ToDateStr
  • Container.Prototype.ToDateStrFromParser
  • Container.Prototype.ToDateValue
  • Container.Prototype.ToMisc
  • Container.Prototype.ToNumber
  • Container.Prototype.ToString
  • Container.Prototype.ToStringPtr
  • Container.Prototype.ValidateSort

Instance methods - Categorized list

This section categorizes the instance methods into the following categories:

Instance methods - Sort methods

Methods that sort the values in the container.

  • Container.Prototype.InsertionSort
  • Container.Prototype.QuickSort
  • Container.Prototype.Sort

Instance methods - Binary search methods

Methods that implement a binary search.

Instance methods - Find methods

Methods that use a binary search to find a value / values in the container.

  • Container.Prototype.EnumRange
  • Container.Prototype.EnumRangeSparse
  • Container.Prototype.Find
  • Container.Prototype.FindAll
  • Container.Prototype.FindAllSparse
  • Container.Prototype.FindInequality
  • Container.Prototype.FindInequalitySparse
  • Container.Prototype.FindSparse
  • Container.Prototype.GetValue
  • Container.Prototype.GetValueSparse

Instance methods - Insert methods

Methods that use a binary search to insert a value into the container, retaining the sort order.

  • Container.Prototype.DateInsert
  • Container.Prototype.DateInsertIfAbsent
  • Container.Prototype.DateInsertIfAbsentSparse
  • Container.Prototype.DateInsertList
  • Container.Prototype.DateInsertListSparse
  • Container.Prototype.DateInsertSparse
  • Container.Prototype.Insert
  • Container.Prototype.InsertIfAbsent
  • Container.Prototype.InsertIfAbsentSparse
  • Container.Prototype.InsertList
  • Container.Prototype.InsertListSparse
  • Container.Prototype.InsertSparse

Instance methods - Delete methods

Methods that use a binary search to find, then delete a value / values, leaving the index / indices unset.

  • Container.Prototype.DeleteAll
  • Container.Prototype.DeleteAllSparse
  • Container.Prototype.DeleteValue
  • Container.Prototype.DeleteValueIf
  • Container.Prototype.DeleteValueIfSparse
  • Container.Prototype.DeleteValueSparse

Instance methods - Remove methods

Methods that use a binary search to find, then remove a value / values, shifting the values to the left to fill in the empty index / indices.

  • Container.Prototype.Remove
  • Container.Prototype.RemoveAll
  • Container.Prototype.RemoveAllSparse
  • Container.Prototype.RemoveIf
  • Container.Prototype.RemoveIfSparse
  • Container.Prototype.RemoveSparse

Instance methods - Date methods

Helper methods involved with using binary search and sort operations on date values.

  • ContainerObj.DateConvert
  • ContainerObj.DateConvertCb
  • Container.Prototype.DatePreprocess
  • Container.Prototype.DateUpdate

Instance methods - Instantiation methods

Methods that define the properties needed to use sort and binary search methods.

  • Container.Prototype.SetCallbackCompare
  • Container.Prototype.SetCallbackValue
  • Container.Prototype.SetCompareStringEx
  • Container.Prototype.SetCompareDate
  • Container.Prototype.SetCompareDateStr
  • Container.Prototype.SetDateParser
  • Container.Prototype.SetSortType
  • Container.Prototype.ToCbDate
  • Container.Prototype.ToCbDateStr
  • Container.Prototype.ToCbDateStrFromParser
  • Container.Prototype.ToCbNumber
  • Container.Prototype.ToCbString
  • Container.Prototype.ToCbStringPtr
  • Container.Prototype.ToDate
  • Container.Prototype.ToDateStr
  • Container.Prototype.ToDateStrFromParser
  • Container.Prototype.ToDateValue
  • Container.Prototype.ToMisc
  • Container.Prototype.ToNumber
  • Container.Prototype.ToString
  • Container.Prototype.ToStringPtr

Instance methods - Iterative methods

Methods that iterate the values in the container, performing some action on them.

  • Container.Prototype.Condense
  • Container.Prototype.Every
  • Container.Prototype.EverySparse
  • Container.Prototype.Flat
  • Container.Prototype.ForEach
  • Container.Prototype.ForEachSparse
  • Container.Prototype.HasValue
  • Container.Prototype.HasValueSparse
  • Container.Prototype.Join
  • Container.Prototype.JoinEx
  • Container.Prototype.Map
  • Container.Prototype.MapSparse
  • Container.Prototype.Purge
  • Container.Prototype.PurgeSparse
  • Container.Prototype.Reduce
  • Container.Prototype.ReduceSparse
  • Container.Prototype.Reverse
  • Container.Prototype.ReverseSparse
  • Container.Prototype.Search
  • Container.Prototype.SearchAll
  • Container.Prototype.SearchAllSparse
  • Container.Prototype.SearchSparse

Instance methods - General methods

  • Container.Prototype.Compare
  • Container.Prototype.Copy
  • Container.Prototype.DeepClone
  • Container.Prototype.Enum
  • Container.Prototype.PushEx
  • Container.Prototype.Slice
  • Container.Prototype.ValidateSort

Instance properties - Alphabetized list

In addition to the properties inherited from Array, Container has the following properties:

  • ContainerObj.CallbackCompare
  • ContainerObj.CallbackCompareValue
  • ContainerObj.CallbackDateInsert
  • ContainerObj.CallbackValue
  • ContainerObj.CompareDateCentury
  • ContainerObj.CompareStringLocaleName
  • ContainerObj.CompareStringNlsVersionInfo
  • Container.Prototype.DateParser
  • ContainerObj.SortType

Instance properties - Categorized list

This section categorizes the instance properties into the following categories:

Instance properties - Dynamic properties

  • Container.Prototype.DateParser

Instance properties - Own properties

  • ContainerObj.CallbackCompare
  • ContainerObj.CallbackCompareValue
  • ContainerObj.CallbackDateInsert
  • ContainerObj.CallbackValue
  • ContainerObj.CompareDateCentury
  • ContainerObj.CompareStringLocaleName
  • ContainerObj.CompareStringNlsVersionInfo
  • ContainerObj.SortType

Miscellaneous info

This section includes miscellaneous info not specifically related to Container but that might be useful.

Binary search

The following is a simple binary search written in AHK code. Container has many variations of this same logic to meet any use case.

BinarySearch(arr, value, comparator) {
    left := 1
    right := arr.Length
    while right - left > 4 {
        i := right - Ceil((right - left) * 0.5)
        if x := comparator(value, arr[i]) {
            if x > 0 {
                left := i
            } else {
                right := i
            }
        } else {
            return i
        }
    }
    i := left
    loop right - i + 1 {
        if comparator(value, arr[i]) {
            ++i
        } else {
            return i
        }
    }
}

Parameter hints

Parameter hints are a feature available in some code editors that, when activated, displays information about a function in a tooltip within the editor.

I've written 95% of my code in Visual Studio Code, so I do not know about other editors. If your code editor does not have this functionality, but you are interested in trying out a new editor, I recommend Visual Studio Code. Be sure to install thqby's AutoHotkey v2 Language Support extension. Also you will want to install a debugger. I have been using vscode-autohotkey-debug but I searched on https://marketplace.visualstudio.com/ right now and AutoHotKey Debug looks promising.

Visual Studio Code is massively customizable and can be intimidating to use at first, but you will get the hang of it over time. Parameter hints are invoked by the action called "Trigger parameter hints". You can customize the keyboard shortcut for this by opening Keyboard Shortcuts (Ctrl+Shift+P > Preferences: Open Keyboard Shortcuts) and searching "Trigger parameter hints".

Changelog

  • 2025-11-06 - v1.0.6

    • BREAKING CHANGES
      • Renamed Container.Prototype.__Enum to Container.Prototype.Enum. The reason for the change is because overriding Array.Prototype.__Enum caused the debugger vscode-autohotkey-debug to fail to display the container's items as child tree-view nodes beneath the container's tree-view node. I don't have the time to commit to figuring out how to adjust the debugger's code to work around this, so instead I renamed the method. Any code that calls Container.Prototype.__Enum and that also expects to receive one of the custom enumerators will need to instead call Container.Prototype.Enum.
    • Changed:
      • Container_DateParser objects now have a property "DateFormat" which contains the string date format that was passed to the first parameter of Container_DateParser.Prototype.__New.
      • if A_LineFile == A_ScriptFullPath to if !A_IsCompiled && A_LineFile == A_ScriptFullPath in test files.
    • Fixed:
      • #include *i NlsVersionInfo.ahk to use the correct file name.
  • 2025-10-10 - v1.0.5

    • Added methods:
      • Container.Prototype.EnumRange
      • Container.Prototype.EnumRangeSparse
      • Container.Prototype.__Enum
    • Added file:
      • test\test-EnumRange.ahk
    • Changed:
      • Removed value "CONTAINER_SORTTYPE_END" from Container.SortTypeSymbolList.
      • Added test_miscExamples.Enum, test_miscExamples.EnumRange, and test_miscExamples.EnumRangeSparse.
  • 2025-10-07 - v1.0.4

    • Changed:
      • Container_SetConstants now sets a global variable container_flag_constants_set to indicate that Container_SetConstants has already been called. Container_SetConstants now has a parameter force which allows the caller to force execution even if Container_SetConstants has previously been called.
  • 2025-10-06 - v1.0.3

    • BREAKING CHANGES
      • Removed parameter Encoding from all methods that previously had it. Any code that called a method with a parameter Encoding that used that parameter will need to delete that parameter. Any code that called a method with a parameter Encoding that used a parameter that occurred after Encoding will need to shift those parameters to the left by 1. The following are affected methods:
        • Container.StringPtr
        • Container.String
        • Container.CbStringPtr
        • Container.CbString
        • Container.Prototype.SetCompareStringEx
        • Container.Prototype.ToStringPtr
        • Container.Prototype.ToString
        • Container.Prototype.ToCbStringPtr
        • Container.Prototype.ToCbString
    • Changed:
      • Container.StrSplit now calls Container.Prototype.ToString from the new Container instance. The parameters for Container.Prototype.ToString were added to Container.StrSplit.
    • Documentation:
      • Added parameter hints to the remaining methods that did not yet have parameter hints.
      • Fixed the parameter hint above Container.Prototype.SetCallbackValue. Previously, it displayed the parameter hint details for Container.Prototype.SetCallbackCompare. It now displays the correct information.
  • 2025-10-04 - v1.0.2

    • Added methods:
      • Container.Prototype.GetValue
      • Container.Prototype.GetValueSparse
    • Changed:
      • test\run-tests.ahk - Changed the name test to Container_RunTests, added in tooltips, and added in a if A_LineFile == A_ScriptFullPath condition to run the tests.
      • Simplified the while condition in all of the "Find" methods.
  • 2025-10-04 - v1.0.1

    • Added methods:
      • Container.Prototype.DateInsertList
      • Container.Prototype.DateInsertListSparse
      • Container.Prototype.InsertList
      • Container.Prototype.InsertListSparse
      • Container.Prototype.ValidateSort
    • Added property:
      • Container.SortTypeSymbolList
    • Added global functions:
      • Container_IndexToSymbol
      • Container_SetSortTypeContainer
    • Added file:
      • test\performance-test-InsertAll.ahk
  • 2025-10-03 - v1.0.0

    • Released v1.0.0

About

An AutoHotkey (AHK) array class with built-in sorting (sorts ANY value), binary search, and common array methods like forEach, join, and more.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published