Lists

Lists and property lists provide two convenient and powerful ways to organize and manipulate data within your scripts. This section presents the key things you must know to fully exploit the power of lists

For more information about working with lists, see Chunk Expressions, and the control structure discussion in Repeat with Each.

In addition to lists and property lists, SenseTalk provides a hierarchical tree structure, which is described in Using XML and Tree Structures in SenseTalk Scripts.

Creating Lists

Create a list in a script by listing two or more expressions separated by commas and enclosing the list in parentheses. Lists must be contained within parentheses or braces. Doing so makes the list syntax clear and consistent, and makes constructing nested lists easier:

Example:

put (1,3,5,7,9) into oddList

Example:

put (("dog", "Fido"), ("cat", "Cleo")) into nestedList // Creates a list of lists

Example:

set myList to ("sandwich",49,the date)

Example:

set TestEnvironments = ("Windows","MacOSX","Android","iOS")

Example:

put "a".."z" into AlphabetList

For longer lists, enclose the list in curly braces { }, which lets the list span multiple lines:

set searchPaths to {

"/Library/WebServer/Documents",

"~/Documents",

"/Users/hemingway/Documents/temp/ImportantStuff" }

Tech Talk

Syntax: ( {expr { , expr}... } )

{ {expr { , expr}... } }

{an} empty list

Here, expr can be any expression, including nested lists, or may be omitted. If any expr is omitted, leaving sequential commas with nothing in between, SenseTalk creates an empty item. SenseTalk ignores a final comma at the end of a list.

List Contents

Include any type of value in a list, including other lists and property lists.You can also use expressions when constructing lists:

Example:

put ("geranium", pi * (2 * radius), (age:42)) into mixedList // "pi_* (2 * radius)" is an expression, and "(age:42)" is a property list

Example:

put (1,(2,(3,4)),5) into nestedList // Stores the list ‘(1,(2,(3,4)),5)’ into a variable.

Single-Item Lists

When a single value is enclosed in parentheses in a script, the parentheses are treated as a grouping operator, so that value will not be treated as a list. To make SenseTalk recognize a single item in parentheses as a list, include a comma after the value:

Example:

put (12,) into shortList // This makes a list with one item

For most purposes, a list containing a single item is treated the same as a single (non-list) value. For example, if myList is (4), that is, a list containing a single item that is the number 4, then use put myList + 2 into theSum. Using this approach, theSum contains the number 6. Normally, when accessing such a list as text, the value shows in parentheses. To avoid this behavior, set the prefix and suffix properties of the listFormat to empty.

Empty Lists

To create an empty list, use an empty pair of parentheses, or the phrase empty list:

Example:

put () into newlist // newlist is now a list with no items

put 16 into item 1 of newlist // (16)

put empty list into item 2 of newlist // (16,())

Inserting Items into a List

Use the insert command to insert items before, into, or after a list or any item of a list. It is somewhat similar to the put command, but always treats the destination container as a list:

Example:

put "abc" into myList // Stores abc (not actually a list) in a variable

put "de" after myList // Appends de to abc resulting in abcde (still not a list)

insert "xyz" after myList // Instantly creates a list by inserting the xyz string, resulting in (abcde,xyz)

insert 24 before item 2 of myList // Inserts an additional item into the list, resulting in the list (abcde,24,xyz)

Example:

put "First, let's connect to our SUT." into instructions // Populates variable instructions with a text string

insert "Next, let's enter Capture Mode." after instructions // Inserts a second text string in order to create a list

put instructions // Displays "First, let's connect to our SUT. Next let's enter Capture Mode.", which appears like a 4-item list based on comma position but is actually a 2-item list

set the listFormat to (prefix:"(",suffix:")",separator:"|") // Changes the listFormat to separate list items with | instead of comma

put instructions // Displays (First, let's connect to our SUT.|Next, let's enter Capture Mode.) making it clear there are only 2 items in the list and not 4

When inserting a list of items into another list, there are two possible ways to complete the insertion. The default mode, known as “item by item," is to insert each item from the source list into the destination list:

Example:

put (1,2,3,4) into list // (1,2,3,4)

insert (A,B) after item 2 of list // Item 2 of list // -- (1,2,A,B,3,4)

It is also possible to insert a list into another to create a nested list by using the nested keyword:

Example:

put (1,2,3,4) into list // (1,2,3,4)

put ("A","B") into otherList // (A,B)

insert otherList nested after item 2 of list // (1,2,(A,B),3,4)

To control the standard insertion behavior, set the listInsertionMode local property or the defaultListInsertionMode global property to either nested or item by item:

Example:

put (1,2,3) into aList

set the listInsertionMode to "nested"

insert (4,5) into aList -- (1,2,3,(4,5))

See the insert command for more information.

Push, Pull, and Pop

The push command is synonymous with the insert command. The pop command removes the last value from a list and stores it into a variable. The push and pop commands treat a list as a stack. Items pushed onto the stack can be retrieved in the reverse order with the pop command.

Example:

put ("carrots","bananas","pistachios") into GroceryList

pop GroceryList into gList

put gList // Returns "pistachios"

The pull command removes the first value from a list and stores it into a variable. The push and pull commands treat a list as a queue. The pull command retrieves items one at a time in the same order that they were added to the queue by the push command.

Example:

put ("carrots","bananas","pistachios") into GroceryList

pull GroceryList into gList

put gList // Returns "carrots"

You can specify which items to pop or pull from a list, as well.

Example:

put ("carrots","bananas","pistachios","lettuce","wasabi") into GroceryList

pull item 4 of GroceryList into gList

put gList // Returns "lettuce"

Combining Lists

To join two lists as one (without nesting), use the &&& operator:

Example:

put (3,4,5) into tr1 // (3,4,5)

put (5, 12,13) into tr2 // (5,12,13)

put tr1 &&& tr2 into longList // Creates one, not-nested list (3,4,5,5,12,13)

put (tr1,tr2) into twoTriples // Creates a nested list - a list of two lists ((3,4,5),(5,12,13))

Accessing List Items

Accessing items within lists, including ranges of items and lists of items, is fully supported using the item and items chunk expressions (or their more explicit forms, list item and list items). Accessing a single item yields the item at that index. Accessing a range of items always yields a list, even when the range specifies a single item:

Example:

put (1,2,3,4,5) into NumberList // (1,2,3,4,5)

put list items 3 to last of NumberList // (3,4,5)

put item 2 of NumberList // Displays "2"

put items 2 to 2 of NumberList // Displays the single-item list ‘(2)’

put items (4,2,5) of NumberList // (4,2,5)

Example:

put ("cheddar","provolone","brie","muenster","mozzarella") into CheeseList

put the penultimate item of CheeseList // displays muenster

put item random(5) of CheeseList // prints a random item from the list

log "My favorite cheese is" & the third item of CheeseList & period // displays "My favorite cheese is brie."

By default, the item term refers to text items rather than list items if the variable in question is not known to be a list. Using the explicit term list item always treats the variable as a list even if it contains a non-list value (in which case it will be treated like a one-item list containing that value).

Example:

put <<"Welcome to Mars", said the alien.>>into NotList

put item 1 of NotList // displays "Welcome to Mars"

put list item 1 of NotList // displays "Welcome to Mars", said the alien

Converting Lists to Text

The split and join commands and functions and the asText function, described in detail in Working with Text, and the corresponding split by and joined by operators (described in Expressions) provide ways to explicitly convert text to lists and vice versa.

Example:

join ("peanut butter","bread","jelly") using "," // Creates the string 'peanut butter,bread,jelly'

When a list needs to be accessed as text (such as when it is displayed by a put command), SenseTalk converts it automatically to a text representation. By default, this conversion is done by enclosing the entire list in parentheses, with the items in the list separated by commas. To change this formatting approach, set the prefix, separator, and suffix values of the listFormat global property. The prefix is the text that is used before the list (usually a left parenthesis), separator is the text inserted between items, and suffix is the text appended after the list. Set these values to any text you like, including empty.

Example:

set the listFormat to (prefix:">>", separator:":", suffix:"<<")

put (1,2,3,4,5) // converts the list to a text representation and displays >>1:2:3:4:5<<

Example:

put (prefix:"+",suffix:"+",separator:empty) into the ListFormat

set Weather to ("windy","rainy","sunny")

log items 2 to 3 of Weather // converts the list to a text representation and displays '+rainysunny+'

When a list is converted to text, each value within the list is converted to a text representation. To control the quoting of these values, set the quotes value of the listFormat global property. For more information about this property, see the listFormat.

Sometimes SenseTalk provides a text representation for what is a complex object. For example, the files() function returns a list of property lists, where each property is an object representing a file. Considering this example, it is possible to work with the asText representation of those files instead of having to treat them as property lists.

Example:

put the files of resourcepath() into files // Stores a list of property list objects representing each of the files inside the Resources section of the suite

put files //Displays the asText representation of each of the file objects in a list. i.e. '(locations.txt,parameters.txt,testcase1.txt,testcase2.txt,testcase3.txt,testcase4.txt)'.

repeat with each myFile of files // Iterates based on each property list in the list

if myFile's NSFileSize is greater than 10 then // We can still access the individual keys of the property list as we are actually working with the objects rather than a text string

put file resourcepath(myFile) // SenseTalk automatically uses the appropriate representation with the ResourcePath() function, allowing us to access the content of the file

end if

end repeat

Converting Text to Lists

The split and join commands and functions and the asText function, described in detail in Working with Text, and the corresponding split by and joined by operators (described in Expressions) provide ways to explicitly convert text to lists and vice versa.

Example:

split "Peter-Paul-Mary" by "-" // Creates the list '(Peter,Paul,Mary)'

When using comma delimited .txt or CSV files in data driven testing, each line of the data file that SenseTalk accesses is a text string rather than a list. This statement is true even if the text string appears to be formatted like a list within the data file. SenseTalk's ability to access and iterate over items within a text string means that no special handling of the input from the file is necessary if you want to treat its contents as if they were lists. However, understanding that you are not actually dealing with a list in these cases can be important in certain situations.

Example:

put (2 ounces,3 ounces,4 ounces) into SizesList

put SizesList * (.5,.2,.7) // Displays the list '(1 ounce,0.6 ounces,2.8 ounces)'.

put line 1 of file resourcePath("sizes.txt") into SizesFile // Line 1 of file sizes.txt contains '2 ounces,3 ounces,4 ounces', which is a text string

put SizesFile * (.5,.2,.7) // The content of the input is not a number and SenseTalk cannot take its value, so the SenseTalk code throws an error when executed

Use the standardFormat function to convert a list to text in a format that will produce the original list again when that text is evaluated by the value function.

Example:

put ("peanut butter","bread","jelly") into Sandwich

put standardformat(Sandwich) into newSandwich //Converts the list into text

put value(newSandwich) into Sandwich // Converts the text into a list

Converting Text Representations to List Structures

In rare circumstances when accessing a list as text, such as with the put or log commands, SenseTalk's automatic conversion of the list into a text representation results in a simplified but undesired structure. Use the asList() to produce the requested list structure, letting SenseTalk display the list in a list-like format. See as operator for more information.

Example:

put "1".."9" into NumberList // creates a list with contents (1,2,3,4,5,6,7,8,9)

log NumberList // displays '1 to 9'

log NumberList as a list // displays '(1,2,3,4,5,6,7,8,9)'

It is possible to reference text items in chunk types. However, this does not mean that the text is a list. The asList() function can be used to convert text into a list, which changes how items are defined and accessed.

Example:

put "A man, a plan, a canal. Panama!" into Palindrome // Stores the text string in a variable. This is not a list.

put the number of items of Palindrome // Returns 3 as there are 3 text items in the text, delimited by comma

put Palindrome is a list // Checks whether Palindrome is a list. Returns false, as the contents are text rather than a list.

put Palindrome as a list into PalindromeList // Stores the text as a list into a new variable

put PalindromeList is a list // Checks whether PalindromeList is a list. Returns true.

put the number of items of PalindromeList // Returns 1, as the list now just contains one item, 'A man, a plan, a canal. Panama!'

Automatic Conversion of Values Within a List

SenseTalk is a typeless language. As such, SenseTalk automatically converts values, including values stored in a list, to an appropriate internal representation.

Example:

put (5 pounds 3 ounces,ten feet 5 inches,400 megabytes and 12 kilobytes) into ValuesList // Automatically converts the values in the list, resulting in the list (5.1875 pounds,10.416667 feet,409612 kilobytes)

put ("5 pounds 3 ounces","ten feet 5 inches","400 megabytes and 12 kilobytes") into StringsList // The list contains text strings, which aren't visibly converted. Results in the list ‘(5 pounds 3 ounces,ten feet 5 inches,400 megabytes and 12 kilobytes)’.

Replacing Items in a List

While the insert command is specifically tailored for working with lists, it only adds new values into a list. To replace existing items in a list with new values, use the set or put into commands.

Note: Unlike put into, the put before and put after commands are rarely used with lists. Their behavior when the destination is a list is to concatenate a text value before or after the first or last item of the list. More often what is wanted is to insert new items before or after a list, using the insert before and insert after commands.

Using the put into or set commands to put one or more new values into a list replaces the entire contents of the destination with the new values. The final result can take several forms:

If the destination container is a variable, SenseTalk discards that variable’s previous contents and replaces it with a copy of the new value(s).

Example:

put "good morning" into greetings

put ("hello","hola") into greetings // Replaces the previous string stored in variable greetings

log greetings // Logs '(hello,hola)'

If the source is a single value and the destination is a single item or a range of items within a list, those items, as a whole, are replaced by the new value:

Example:

put (1,2,3,4) into aList

put 99 into items 2 to 3 of aList // Results in the list '(1,99,4)

If the new value is a list rather than a single value, the result is a nested list if the destination is a single item:

Example:

put ("hazel","black","blue") into eyeColors

put ("green","brown") into the first item of eyeColors // Results in the list '((green,brown),black,blue)'

If the destination is a range of items (even a 1-item range), those items are replaced by the new values:

Example:

put (1,2,3,4) into aList

put ("a","b","c") into items 2 to 3 of aList // Results in the list '(1,a,b,c,4)'

put ("x","y") into items 1 to 1 of aList // Results in the list '(x,y,a,b,c,4)'

These results can be controlled explicitly by specifying “item by item” or “nested”:

Example:

put (1,2,3,4) into aList

put ("a","b","c") nested into items 2 to 3 of aList // Results in the list '(1,(a,b,c),4)'

set item 1 of aList to ("x","y") item by item // Results in the list '(x,y,(a,b,c),4)'

The listInsertionMode and defaultListInsertionMode properties, described earlier, also apply when the destination is a range of items and “nested” or “item by item” is not stated explicitly (some of the examples shown above assumed the default “item by item” setting for these properties).

You can store values into several items at once by specifying a list of indexes to store into:

Example:

set notes to "c,d,e,f,g"

put "#" after items (1,4) of notes // Results in the list '(c#,d,e,f#,g)'

Example:

put ("taurus","gemini","andromeda","cygnus","ursa major") into Constellations

set items (3,1) of Constellations to ("sagittarius","orion") // Results in the list '(orion,gemini,sagittarius,cygnus,ursa major)'

You can store a single value into multiple items at once:

Example:

put (1,2,3,4) into aList

put "Egg" into items (6,4,2) of aList // Results in the list '(1,Egg,3,Egg,,Egg)'

Deleting Items from a List

Use the delete command to delete one item or a range of items from a list, using the standard chunk expression syntax:

Example:

put ((100,100),(200,200),(300,300),(400,400),(500,500)) into MovetoLocations

delete item 4 of MovetoLocations // Results in the list '((100,100),(200,200),(300,300),(500,500))'

Example:

put ("c","d","e","f","g") into notes

delete the last 2 items of notes // Results in the list '(c,d,e)'

Deleting Characters from a List

Use the delete command to delete particular characters or strings of characters from the list. SenseTalk deletes the specified string of characters from each item in the list.

Example:

put ((100,100),(200,200),(300,300),(400,400),(500,500)) into MovetoLocations

delete zero from MovetoLocations // Results in the list '((1,1),(2,2),(3,3),(4,4),(5,5))'

Counting the Items in a List

Use the number function to find out how many items are in a list, by asking for the number of items (if the source is known to be a list) or explicitly for the number of list items (if it may not be a list):

Example:

put the number of items in (1,3,4,5,9) // Returns '5'

Example:

put "Akron, OH" into City

put the number of list items of City // Returns '1'

Determining the Location of an Item in a List

The item number of ... within ... expression gives the item number of a value within a list, or zero if that item is not found in the list:

Example:

put "a".."z" into AlphabetList

put the item number of "c" within AlphabetList // Returns '3'

The item number containing ... within ... expression gives the number of the first item in a list that contains the given value, or zero if that value is not found in the list:

put ("dog","cat","armadillo") into Animalia

put the item number containing "c" within Animalia // Returns '2'

Performing Arithmetic on Lists

Vector arithmetic is supported by lists.

You can add or subtract two lists of numbers, provided they are both the same length. This approach adds or subtracts the corresponding items of the two lists. Vector operations work with nested lists as well.

Example:

put (12,4,6,22) into numList

add (1,2,3,4) to numList // Results in the list '(13,6,9,26)'

Multiplication and division of lists also works for lists of equal length.

Example:

put (6,7,14,33) divided by (3,2,1,3) // Results in the list '(2,3.5,14,11)'

put (4,5,6) * (9,8,7) // Results in the list '(36,40,42)'

You can also multiply or divide a list by a single value (sometimes called a ‘scalar’ because it scales all the values in the list).

Example:

put (6,7,14,33) / 2 //Results in the list '(3,3.5,7,16.5)'

Example:

put (12 pounds,15 pounds,13 pounds) into myCatsWeights

put .75 into DietRequirements

log myCatsWeights times DietRequirements // Results in the list '(9 pounds,11.25 pounds,9.75 pounds)'

List Comparisons

The comparison operators treat lists differently than single values. The =, <>, <, >, <=, and >= operators go through lists item-by-item, comparing individual values to determine equality or inequality. For equality, there must be the same number of items in both lists, and each matching pair must be equal. For inequality, the first unequal pair of items determines the order. If the lists are of unequal length but are equal for every item in the shorter list, the longer list is considered greater. A plain (non-list) value is treated like a list with a single item when it is compared to a list.

Example:

put (3 - 2,02.00,A) = (1,2,"a") // True unless caseSensitive is set

put (1,2,2) < (1,2,3) // True

put (1,2) is less than(1,2,0) // True

put (1,2,3) , (1,3) // True

put (1,2,3) < 5 // True, because 1 is less than

Example:

put ("China","Japan","South Korea","Cambodia") equals ("China","Japan","Cambodia","South Korea") // False

The begins with, ends with, is in, and contains operators all check for the presence of whole values or sequences of values in the list, whenever the value being searched is a list. These operators all look deeply into nested lists. When the value being looked for is also a list, its items must appear in the same order within the list or one of its sublists in order to match.

Examples:

put ("a","b","c") begins with ("a","b") // True

put ("a","b","c") begins with "a" // True

put (1,2,3) ends with (2,3) // True

put (1,2,3) ends with 3 // True

put ("some","choice","words") contains ("words","choice") // False

put ("some","choice","words") contains "word" // False

put (3,4)is in ((1,2),(3,4,5)) // True

put (2,3) is in ((1,2),(3,4,5)) // False (not in the same sub-list)

Iterating Over Items in a List

To perform actions with each of the values in a list, you can step through the list’s values using a repeat with each item loop. This approach sets the it variable to each of the values of the list in turn:

Example:

repeat with each item of 1..5

log "The cubed value of "&it&" is"& it cubed

end repeat

To use a variable other than it, include a variable name after the word item:

Example:

set TestList to ("regression","smoke","performance")

repeat with each item Test of TestList

RunWithNewResults Test

end repeat

To modify items in a list, including changing their values or even deleting them, specify by reference. This approach sets the loop variable to be a reference to each of the items instead of a copy of their values:

Example:

set numList to (10,11,12,13,14,15,16)

repeat with each item of numList by reference

if it is an odd number then delete it

else divide it by 2

end repeat

put numList // Results in the list '(5,6,7,8)'

Selecting List Items Using "each" Expressions

The use of each expressions to obtain a list of selected chunks of a value is described in Extracting a List of Chunks. Similarly, to extract a sublist of selected items from a list, use an each expression with a where clause:

Example:

set numList to 9..16

put each item of numList where each is an odd number // Displays the list '(9,11,13,15)'

put each item of numList where sqrt(each) is an integer // Displays the list '(9,16)'

Example:

set Locations to ("Lansing, Michigan","Portland, Oregon","Denver, Colorado","Fort Collins, Colorado")

put each item of Locations where each contains "Colorado" into ColoradoCities // Stores a list of two items: '(Denver, Colorado,Fort Collins, Colorado)' into a variable

Note: For more information about each expressions, see Each Expressions and Iterators.

Applying Operations to Lists Using "each" Expressions

To perform an operation on each item in a list, giving a list of the resulting values, use an each expression (with or without a where clause) as an element of a larger expression:

Example:

set numList to (9,10,12,16)

put each item of numList + 3 // Displays the list '(12,13,15,19)'

put sqrt of each item of numList // Uses the sqrt() function to calculate the square root of each number in the original list, and displays the resulting list '(3,3.162278,3.464102,4)'

put each item of numList * (2,9,3,4) // Displays the list '((18,81,27,36),(20,90,30,40),(24,108,36,48),(32,144,48,64))'

Example:

put (1000 dollars, 5500 dollars, 3600 dollars) into InitialSavings

put each item of InitialSavings * compound(.95%,12) rounded to 2 into FinalSavings // Uses the compound() function to calculate the interest, and stores the resulting list '($1120.15,$6160.82,$4032.54)' into the FinalSavings variable

These expressions can be complex, with multiple operations being applied to each item from the each expression. Enclosing parentheses limits the scope of the each expression: operators within the parentheses apply to each item of the list; operators outside the parentheses apply to the list as a whole.

Sorting the Items in a List

To sort a list, use the sort command or sorted operator. Sorting a list can be as easy as:

Example:

set planets to ("Mars","Saturn","Venus","Earth")

sort planets // Sorts the items of myList into ascending (alphabetical) order. Results in the list '(Earth,Mars,Saturn,Venus)'.

Additional sort options can also be given, including indicating order and options to evaluate property values of lists within the list (see the description of the Sort command in for more information):

Example:

put ((age:14,name:"Monica"),(age:22,name:"Brad"),(age:9,name:"Sam"),(age:12,name:"Michael")) into siblings //This is a list of property lists

sort siblings in descending numeric order by the age of each // Results in the list '((age:"22", name:"Brad"),(age:"14", name:"Monica"),(age:"12", name:"Michael"),(age:"9", name:"Sam"))'

You can sort a list on-the-fly using the sorted operator:

Example:

put (90,88,92,98,91) into Scores

put the first three items of (Scores sorted in decreasing order) // Displays the list '(98,92,91)'.

 

This topic was last updated on February 26, 2019, at 10:29:15 AM.

Eggplant icon Eggplant.io | Documentation Home | User Forums | Support | Copyright © 2019 Eggplant