Author Topic: (Text) Arrays, Numbered Lists, LUT  (Read 7989 times)

ralf44

  • Newbie
  • *
  • Posts: 41
(Text) Arrays, Numbered Lists, LUT
« on: December 13, 2016, 12:29:14 PM »
I have searched the manual and forum and can't find any reference to these. If the functionality exists, please point me to it!

Otherwise I suggest text arrays as a new feature. This would allow a large collection of words/TTS responses/text fragments to be associated with integers, from 0 or 1 to the number of list items.

Without the feature I think that a vast chunk of repetitive IF/ELSE code is required as a Look-Up Table with an IF statement for every numbered item of the list and another huge chunk of code to do reverse look-ups?

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: (Text) Arrays, Numbered Lists, LUT
« Reply #1 on: December 13, 2016, 02:26:12 PM »
I don't have proper arrays in VA, but, by using nested tokens you can simulate them:

Set integer [~i] value to 0
Set integer [myVar({INT:~i})] value to 10
Write '[Blue.] {INT:myVar({INT:~i})}' to log

Writes, '10' to the log.  Note that you don't need parenthesis.  Also, the, '~' is new as of last beta (indicates command-scoped variable).

It's white-boarded to add, 'arrays', but what will happen behind the scenes will pretty much be what you see above.
« Last Edit: December 13, 2016, 02:34:51 PM by Gary »

Exergist

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 405
  • Ride the lightning
Re: (Text) Arrays, Numbered Lists, LUT
« Reply #2 on: April 21, 2017, 01:22:01 PM »
I wholeheartedly second this request. This would add a world of potential, especially for dynamically declaring and calling variables.

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: (Text) Arrays, Numbered Lists, LUT
« Reply #3 on: April 21, 2017, 01:46:52 PM »
I'm kind of leaning on leaving it like it is, as it seems to do what it needs to do :

Set text [myText(0)] value to 'Moe'
Set text [myText(1)] value to 'Larry'
Set text [myText(2)] value to 'Curly'
Write '[Blue.] {TXT:myText(2)}' to log  (writes, 'Curly' to log)

-or-

Set integer [~i] value to 0
Set integer [myVar({INT:~i})] value to 10

Write '[Blue.] {INT:myVar({INT:~i})}' to log


The only thing lacking is being able to ask for an array size from something.  The onus for that would be on you.  What is missing that I'm missing?

With the new, 'for' loops, it makes this stuff easier.

Exergist

  • Global Moderator
  • Sr. Member
  • *****
  • Posts: 405
  • Ride the lightning
Re: (Text) Arrays, Numbered Lists, LUT
« Reply #4 on: April 21, 2017, 02:31:22 PM »
Using the syntax you provided I suppose 2D arrays could be crafted as follows:

Set Text [myArray[1,1]] to 'Moe'
Set Text [myArray[2,1]] to 'Larry'
Set Text [myArray[3,1]] to 'Curly'
Set Text [myArray[1,2]] to 'likes'
Set Text [myArray[1,3]] to 'pie'
Write '[Blue.] {TXT:myArray[1,1]} {TXT:myArray[2,1]} {TXT:myArray[3,1]}' to log (writes 'Moe Larry Curly' to log)
Write '[Blue.] {TXT:myArray[1,1]} {TXT:myArray[1,2]} {TXT:myArray[1,3]}' to log (writes 'Moe likes pie' to log)

...and as you described the above numbering could instead by integer variables that could be looped through for initialization and/or calling.

But that could quickly turn into a LOT of variables that get initialized and called upon. I'm not sure from a resource use or efficiency point of view whether VA is best suited for the above array execution (lots of variables storing minimal data) vs actual array variables (minimal array variables storing lots of data).

But maybe it's all a wash and I wasn't able to wrap my head around your initial example (it did 'click' for me after reading your Moe Larry Curly example though).

Rhaedas

  • Jr. Member
  • **
  • Posts: 72
Re: (Text) Arrays, Numbered Lists, LUT
« Reply #5 on: April 21, 2017, 02:36:54 PM »
Lol, thanks Gary, and ralf44. I just did a Google search around this morning to try and figure out if and how to do an array type thing in VA (for work-related, not gaming this time), and ta-da! This should work out well, not doing anything complex, but did need the flex of a numbered variable. Probably would have stumbled upon it eventually messing with things, but you made it easy. :)

Gary

  • Administrator
  • Hero Member
  • *****
  • Posts: 2832
Re: (Text) Arrays, Numbered Lists, LUT
« Reply #6 on: April 21, 2017, 05:47:28 PM »
The only real overhead behind the scenes that is not efficient is that the naming is going to cause a lot more bloat than a standard array.  Not sure if it's *that* much, though... unless we're talking about thousands and thousands of elements.  At that point, you might want to look at inline functions or plugins if you need absolute speed and efficiency.

Pfeil

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 4782
  • RTFM
Re: (Text) Arrays, Numbered Lists, LUT
« Reply #7 on: June 10, 2019, 04:51:26 AM »
With both this recent topic and my own need for iterating over a bunch of values, I'd like to bring this request up again.


While the functionality can be emulated using variable variable names, doing so requires a bunch of actions, resulting in a difficult to read and maintain action list.

E.G. I used
Code: [Select]
Start Loop : Repeat From 0 to 2
    Begin Integer Compare : [~i] Equals 0
        Set Text [token] to 'PROCESSEXISTS'
    Else If Integer Compare : [~i] Equals 1
        Set Text [token] to 'WINDOWEXISTS'
    Else If Integer Compare : [~i] Equals 2
        Set Text [token] to 'PROCESSFOREGROUND'
    End Condition
End Loop

where I could use
Code: [Select]
Set Text [list0] to 'PROCESSEXISTS'
Set Text [list1] to 'WINDOWEXISTS'
Set Text [list2] to 'PROCESSFOREGROUND'
Set integer [i] value to 0
Start Loop While : [{TXT:list{INT:i}}] Does Not Equal 'Not Set'
    Set Text [token] to 'list{INT:i}'
    Set integer [i] to [i] plus 1
End Loop

but would much prefer to use something like
Code: [Select]
Set List [myList] to 3 items
Start Loop : Each item in [myList] to 'token'
End Loop

and, in some situations, would love to use
Code: [Select]
Set List [myFirstList] to 3 items
Set List [mySecondList] to 3 items
Start Loop : Repeat From 0 to [{LISTCOUNT:myFirstList}]
     Write [Blue] '{LIST:myFirstList:i} {LIST:mySecondList:i}' to log
End Loop

or, in others, like in the mentioned topic:
Code: [Select]
Begin List Search : [myList] has an item that Contains 'text'
End Condition
or
Code: [Select]
Begin List Search : [myList] has an item that Equals 'text'
End Condition


And all this is without getting into appending or inserting values in a variable sequence.



If I'm dreaming of this functionality anyway, these features, mainly modeled on System.Collections.Generic.List<string>, seem like they would be useful:



A "Set Item Values for a List" action, supporting:

Append literal item values (with token support), or another list (I.E. List<string>.Add)


Append items with their values derived from splitting a text value, with user-provided separator(s) (I.E. String.Split)


Clear variable value (I.E. List<string>.Clear)


Insert literal item values (with token support), or another list, at a given index (I.E. List<string>.Insert)


Remove item value by text (I.E. List<string>.Remove)

Remove all item values by text (I.E. List<string>.RemoveAll)

Remove item value by index (I.E. List<string>.RemoveAt)

Remove item values by index (from / to) (I.E. List<string>.RemoveRange) (to at least somewhat simplify the UI, this would be the only option supporting a range; If it is required to insert or append a range, an additional "Set Item Values for a List" action could be used first to remove the undesired items)


Alphabetize item values (I.E. List<string>.Sort())



A "Begin a Conditional (If Statement) Block" action "List" tab, supporting:

One or more item values Equal / Do Not Equal / Start With / Do Not Start With / Contain / Do Not Contain
Checked against a text token or literal value

Lists would have to allow null values (as strings are nullable), and checking the difference between null and and the literal text "Not Set" could be useful, so One or more item values Have Been Set / Have Not Been Set as well.

In addition,
List Equals / Does Not Equal another list
List Has been Set / Has Not Been Set


Individual item value checks could be done using the "{LIST:}" token in the "Text" tab, otherwise an optional index numericUpDown that only works for values and not whole lists is required.




A '{LISTPOS: textVariableName / text name : textVariableItemValue / text itemValue}' token (I.E. List<string>.IndexOf)



A '{LISTLASTPOS: textVariableName / text name : textVariableItemValue / text itemValue}' token (I.E. List<string>.FindLastIndex)



A '{LIST: textVariableName / text name : intVariableIndex / int index}' token, which allows retrieving a single item's value by its index (I.E. List<string>.Item[])



A '{LISTCOUNT: textVariableName / text name }' token that outputs the number of items in the list (I.E. List<string>.Count)



A '{LISTTXT: textVariableName / text name : textVariableSeparator / text separator }' token that outputs all items in the list with a chosen separator in between (E.G. '{LISTTXT:myList:", "}' to generate a csv, or '{LISTTXT:myList:";"}' for use with other VoiceAttack features)



On top of all that, as it would be a standard List<string>, using it in inline functions would be simple, and allow methods not exposed through the GUI/tokens like "Reverse" or "InsertRange".

This would also provide a way for inline function to store and pass data without having to encode and decode it to a delimited string (you'd still need to switch datatypes, but that's relatively painless if you're using simple datatypes, as the "ConvertAll" method does this for you).




Lastly, here's a slapped-together mockup of the "Set Item Values for a List" window:




That's 99% of the hard work done already, right? ::)
« Last Edit: June 16, 2019, 12:00:06 PM by Pfeil »