Array tutorials

2,827 views
Skip to first unread message

Mitchell Greenfield

unread,
May 26, 2013, 2:10:56 PM5/26/13
to tas...@googlegroups.com
Does anyone know of any good tasker array tutorials?

Mike L

unread,
May 26, 2013, 3:07:34 PM5/26/13
to tas...@googlegroups.com
Rich D helped me to understand variable arrays in this thread here.

The bottom of this page contains some useful syntax for dealing with arrays, as well as creating them.


I've been messing with them and have a decent hold on what can be done with them. I have a "Clock In/Out" profile for work. An NFC tag is linked to a task the adds 1 to the variable %ClockedHours. This profile does stuff when %ClockedHours equals 1 or 2, and shows some basic use of variable arrays.

Profile: Clocked Hours (65)
State: Variable Value [ Name:%ClockedHours Op:Maths: Isn't Equal To Value:0 ]
Enter: Anon (66)
<Clock In>
A1: If [ %ClockedHours = 1 ]
A2: Write File [ File:Tasker/Work Week/Hours Worked Text:%DAYW,%TIMES, Append:On Add Newline:Off ] 
A3: Read File [ File:Tasker/Work Week/Hours Worked To Var:%weeksofar ] 
A4: Variable Split [ Name:%weeksofar Splitter:, Delete Base:Off ] 
A5: End If 
<Clock Out>
A6: If [ %ClockedHours = 2 ]
A7: Variable Set [ Name:%hourstoday To:%TIMES - %weeksofar(<) Do Maths:On Append:Off ] 
A8: Variable Set [ Name:%hourstoday To:%hourstoday / 3600 Do Maths:On Append:Off ] 
A9: Flash [ Text:Worked %hourstoday Today Long:Off ] 
A10: Variable Set [ Name:%weeksofar(<) To:%hourstoday Do Maths:Off Append:Off ] 
A11: Write File [ File:Tasker/Work Week/Hours Worked Text:%weeksofar(:) Append:Off Add Newline:Off ] 
<End of week>
A12: If [ %weeksofar(:) ~ *friday* ]
A13: Variable Set [ Name:%weekworked To:%weeksofar2 + %weeksofar4 + %weeksofar6+ %weeksofar8 + %weeksofar10 Do Maths:On Append:Off ] 
A14: Flash [ Text:Worked %weekworked this week! Long:Off ] 
A15: Variable Clear [ Name:%weekworked Pattern Matching:Off ] 
A16: Delete File [ File:Tasker/Work Week/Hours Worked Shred Level:0 Use Root:Off ] 
A17: End If 
A18: Variable Clear [ Name:%weeksofar Pattern Matching:Off ] 
A19: Variable Clear [ Name:%hourstoday Pattern Matching:Off ] 
A20: Variable Set [ Name:%ClockedHours To:0 Do Maths:Off Append:Off ] 
A21: End If 


This profile works but it is slow so I am in the middle of optimizing it. Let me know if there's anything specific I can answer for you.

Mike L

unread,
May 26, 2013, 3:08:06 PM5/26/13
to tas...@googlegroups.com

Mitchell Greenfield

unread,
May 26, 2013, 3:59:13 PM5/26/13
to tas...@googlegroups.com
So I have read the pocketables guide and I am still confused.  Here is what I am trying to do:

I have a really great project and I have scenes where users can input words that I do text to speech on. I want to allow them to input multiple strings w/commas between them and then if it matches anyone of the array elements execute the same command. So it doesn't matter which part of the array is matched. For each array, if there is a match, execute 1 thing. I understand I need a for loop but I don't understand how to put it all together. I have a scene Commands Pro New 1 where the user has input on %Command1. I am not sure how to make that an array.

To add more detail, i have user input variables %Command1 - %Command10.  I want each to be an array with , seperated values.  Then I have another task where a user says a word and google does TTS.  I then try to match the %voice to the %Command1 and so on.  I know I need to change this to use For loops to go thru each element of the Array but that is where I am stuck.

Mike L

unread,
May 26, 2013, 4:34:30 PM5/26/13
to tas...@googlegroups.com
There's some stuff on flow control here and in the user guide

Mitchell Greenfield

unread,
May 26, 2013, 4:48:48 PM5/26/13
to tas...@googlegroups.com
I read that this morning. I understand the logic but I am stuck on the execution.

Matt R

unread,
May 26, 2013, 5:50:46 PM5/26/13
to tas...@googlegroups.com
You could do something as simple as
if %Command() ~ *%voice*

Matt

Mitchell Greenfield

unread,
May 26, 2013, 5:52:59 PM5/26/13
to tas...@googlegroups.com
I don't think that would work. Because its like i have an array or arrays. Users input %command1-20. Then each can be array and I need to split the, and then search each

Matt R

unread,
May 26, 2013, 7:38:28 PM5/26/13
to tas...@googlegroups.com
So %Command1 is actually an array itself (as is %Command2, etc.)? You can't really have (Tasker) arrays within arrays. Tasker arrays are linear one-dimensional arrays. Maybe instead you could have something like %FirstCommand, %SecondCommand, etc. I'm not clear on what exactly you're trying to do with this set of 2D arrays. Maybe you could explain that more.

Matt

Bob Hansen

unread,
May 26, 2013, 7:40:19 PM5/26/13
to tas...@googlegroups.com
It would be helpful to us if you provided an example or two of what you expect %VOICE variable would be and an example of what %COMMAND1 variable would contain.


Mitchell Greenfield

unread,
May 26, 2013, 8:49:19 PM5/26/13
to tas...@googlegroups.com
Ok, so I think I get the idea.  Instead of using %Command1, I would change the text input box to be %FirstCommand and then use a variable split to load the load array with the users input , separated.

Let's say it was loaded as:
%FirstCommand(1) = Living Room On
%FirstCommand(2) = Family Room On

Than %Voice = living room on

So the for loop...This is where I am confused

Variable : %FirstCommand(#)

Items:  ? Would this just be %FirstCommand(:)

THat is where I am confused

Then I would have an if %FirstCommand(:) = %Voice
   Do Something
End For

So if any if the Variables loaded into %FirstCommand were right, it would do the same thing

Does this make sense? Where am I lost..I feel like I am pretty close...


An Example For loop would really help

Mitchell Greenfield

unread,
May 26, 2013, 9:12:52 PM5/26/13
to tas...@googlegroups.com
Here is what I have so far:

Parse New (414)
A1: For [ Variable:%FirstCommand(#) Items:%FirstCommand() ] 
A2: Flash [ Text:%FirstCommand() Long:Off ] 
A3: If [ %FirstCommand() ~ %Vtemp ]
A4: Variable Set [ Name:%ButtonPressed To:1 Do Maths:Off Append:Off ] 
A5: Flash [ Text:Settings button Long:Off ] 
A6: End If 
A7: Flash [ Text:In loop Long:Off ] 
A8: End For 
A9: Flash [ Text:Loop over Long:Off ] 

I know this doesn't work.  I am not sure what Variable I need to put inside %FirstCommand(XX) to get it to give me the index of the pass thru the For loop....

I don't see that in any of the documentation

Matt R

unread,
May 26, 2013, 11:15:02 PM5/26/13
to tas...@googlegroups.com
I think you're thinking of something like

For variable:%this items:%FirstCommand()
If %this ~ %temp
Do whatever
End if
End for

But if you're just trying to see if %vtemp appears anywhere in the %FirstCommand array, it would still seem best to do

If %FirstCommand ~ *%vtemp*
Do whatever
End if

Matt

Bob Hansen

unread,
May 26, 2013, 11:19:05 PM5/26/13
to tas...@googlegroups.com
This line is wrong

A1: For [ Variable:%FirstCommand(#) Items:%FirstCommand() ] 
%FirstCommand(#) returns the number of items in the array
It should be
A1: For [ Variable:%item, %FirstCommand ] 

Also, based on the info in the posts, you defined each item directly with %FirstCommand1 = this; %FirstCommand2 = that; etc.

It is necessary to build the %FirstCommand array by using the Variable Join action.
Variable Join %FirstCommand  separator "," (comma without quotes) before any loop can be started

Still studying to develop the logic flow to suggest.

Bob Hansen

unread,
May 26, 2013, 11:30:00 PM5/26/13
to tas...@googlegroups.com
What do the %FirstCommand(n) entries represent? Are they the names of tasks to be used to start the requested command? How do you reference the matching %FirstCommand's associated action? By number? By name? Have you decided?

Bob Hansen

unread,
May 27, 2013, 12:00:03 AM5/27/13
to tas...@googlegroups.com
I have tried to define a method to do what you want.... I hope. It is rough and untested but hopefully it will help you.

Based on your example, you do not need a loop. In your example you simple want to compare the phrase in %VOICE  to the phrases in %FirstCommand1, %FirstCommand2, %FirstCommand3........... if the %VOICE matches one of the commands then do whatever is associated with that command. 

I would suggest using each command phrase as the task name that will start the execution of the matched command. Doing this (I believe) will allow you to simplify the code. I used a counter loop for this because I needed the index number.

Logic wise it would look like this:
A1: Variable Join %FirstCommand ","
A2: Get speech-to-text result to %VOICE
A3: Set variable %aMatch to 0    <== aMatch will hold the index number of the matched command
A4: Set variable maxcount = %FirstCommand(#)   <== get the number of items in the array
A5: Set variable %count to 1   <== initialize the loop counter
A6:If %VOICE ~ %FirstCommand(%count) then
A7:      aMatch = %count    <== save the index number of the matched command
A8:      Goto A14     <== got a match get out of the loop
A9: Endif
A10  Variable Add %count, 1      <== increment the index counter
A11: If %count < %maxcount + 1     <== see if we are at the end of the array
A12:    Goto A5                               <== goto the beginning of the loop to test the next item
A13: Endif 
A14: If aMatch = 0                        <== there was no match
A15:    Stop                                    <== so stop
A16: Else                                      <== there was a match
A17:    Perform Task %FirstCommand(%aMatch)         <== perform task to execute requested command
A18: Endif

Mitchell Greenfield

unread,
May 27, 2013, 6:19:48 AM5/27/13
to tas...@googlegroups.com
Thank you for your help!

That makes a lot sense.  One last question.

So I have a TextEdit Field where %FirstCommand is input separated by ,.  So you can enter run around, jump high into %FirstCommand and then I was going to use a variable split to load that into an array.  Is that not the correct way to do it.

Mitchell Greenfield

unread,
May 27, 2013, 6:49:44 AM5/27/13
to tas...@googlegroups.com
I like the idea of :

If %FirstCommand ~ *%vtemp*
Do whatever
End if


But the collision domain is too big.

Mitchell Greenfield

unread,
May 27, 2013, 6:58:58 AM5/27/13
to tas...@googlegroups.com
Bob,

isn't the code you layout similar to what a For loop would do?


On Monday, May 27, 2013 12:00:03 AM UTC-4, Bob Hansen wrote:

Mitchell Greenfield

unread,
May 27, 2013, 7:21:16 AM5/27/13
to tas...@googlegroups.com
Here is the code I came up with using a For loop..but it still doesn't work.  It prints out each item in the loop but doesn't match...

Take 5 (415)
A1: Variable Set [ Name:%Vtemp To:%VOICE Do Maths:Off Append:Off ] 
A2: Variable Convert [ Name:%Vtemp Function:To Lower Case Store Result In: ] 
A3: Variable Set [ Name:%ButtonPressed To:0 Do Maths:Off Append:Off ] 
A4: Flash [ Text:Voice command was: "%Vtemp" Long:Off ] If [ %Denabled ~ true ]
A5: For [ Variable:%item Items:%FirstCommand() ] 
A6: Flash [ Text:%item Long:Off ] 
A7: If [ %Vtemp ~ %item ]
A8: Flash [ Text:Match Long:Off ] 
A9: Variable Set [ Name:%ButtonPressed To:1 Do Maths:Off Append:Off ] 
A10: End If 
A11: End For 

Mitchell Greenfield

unread,
May 27, 2013, 7:23:44 AM5/27/13
to tas...@googlegroups.com
So my code below will work but its load the array with an extra space..need to figure out how to remove that.

Bob Hansen

unread,
May 27, 2013, 9:17:27 AM5/27/13
to tas...@googlegroups.com
Glad to see your making progress

The reason I used an indexed loop is because I wanted to use the index number to point to the matched command in order to launch the appropriate task. Without an index, it will be necessary to use a long list of if-then-do statements. 

You didn't specify where the extra space was located but I suspect it is at the end. You could try to remove it, but I think it would be easier and faster to simply add a space to the other side of the match (%sidea ~ %sideb + ' ').

I don't understand what you mean by:

Mitchell Greenfield

unread,
May 27, 2013, 9:21:07 AM5/27/13
to tas...@googlegroups.com
What I mean by the collision domain being too big is that if I have:
%FirstCommand(1) = tv room on
%FirstCommand(2) = Something room on

Then they both match because of the match of room on if voice = room on.


I think I have everything I need.  I am not going to worry about the space for now.

But the space came into play doing variable splitting,  If I had %FirstCommand = Living room on, tv room on then I did a split on , I ended up with the extra space before tv room on.

Bob Hansen

unread,
May 27, 2013, 10:22:04 AM5/27/13
to tas...@googlegroups.com
Based on how you are doing the matching now, you are comparing a voice phrase to a command phrase so your matching phrases and not word by word. That means the commands can't overlap and no collisions.

As for the space, well that's a human thing. Tasker would not put a space after a comma separator. 

Rich D

unread,
May 27, 2013, 5:34:23 PM5/27/13
to tas...@googlegroups.com

Not to add confusion to the mix but hopefully add some useful suggestions...

Here is a brief outline of how I would approach this..

This is how I understand what you are trying to do..

You want the user to be able to type in the data and have it end up in a comma separated list. Like this..
%Command1 = "living room on,bedroom on,my room on"
%Command2 = "garage on,basement on,attic on

For this part I would use the voice input as well. This will help eliminate matching problems as the engine that creates the arrays will be the same one that creates the search variable.  So use the get voice, covert it to lower case, trim leading and trailing white spaces then present it back to the user for verification then append it to %Command1 adding a comma to the end of course. Make sure you start the %Command1 with a comma so it looks like this..
%Command1 = ",living room on,bedroom on,my room on"
This will make searches easier as well..

I like Bobs Idea about using the index number to reference the task to perform for the matching Command. However I believe you can do it much faster and easier without using a for loop.

Check the user guide in variables / arrays and look for..

%arr(#?b/c) A comma-separated list of the array indices (lowest to highest) with matching values,or 0 if none match (2,3 in the example)

So when you get your voice search criteria and convert it to lowercase, trim out the white spaces and set it to %tempvoice you would search the array like this

Set %indexmatch = %Command(#?,%tempvoice,) // Note the commas, this should address your issue with collision domain //

Now %indexmatch will contain one of the following

1.   %indexmatch ---   this means there were no matches and it did not get set
2.    2,3 ---   this means it matched %Command2 AND %Command3

3.     4 ---     this means the only match was in %Command4

After some "IF" statements to figure out what the match was and act accordingly,  proceed as Bob recommended with the Perform task...

Hopefully this helps...  Rich..

Rich D

unread,
May 27, 2013, 6:10:17 PM5/27/13
to tas...@googlegroups.com

Oops..
*** EDIT ***

> Now %indexmatch will contain one of the following // you should check to see the actual value of %indexmatch to make sure the following is Correct //

>
> 1.     0 ---   this means there were no matches and it did not get set

Rich D

unread,
May 27, 2013, 8:40:10 PM5/27/13
to tas...@googlegroups.com

** one more edit....  :(

> Set %indexmatch = %Command(#?*,%tempvoice,*) // Note the commas, this should address your issue with collision domain //

I added the * before and after the commas.....

Mitchell Greenfield

unread,
May 27, 2013, 8:52:27 PM5/27/13
to tas...@googlegroups.com
Thank you for all your help!
Reply all
Reply to author
Forward
0 new messages