Skip to main content
Version: 23.5

Ranges

Defining a Range

Use a range in SenseTalk to indicate a range of values. A range is specified by giving a start value and an end value, using either a double-dot operator (two periods in a row, ..) or the word to between the two values.

Syntax:
{from} startValue [ to | .. ] endValue { [{step{ping}} {down} by | step] stepvalue }

Example:

put 1 to 100 into firstHundred
set validRange to 100..200

A range may optionally include a step value, using the word by or step or step by (the use of step values is described in "Using a Range to Generate a List", below):

Example:

put 1 to 99 step by 2 into oddNumbers
set evenNumbers to 0..100 by 2

Simple Uses of Ranges

In its simplest uses, a range specifies two values. Access the start and end values directly, as properties of the range:

Example:

set myRange to 10 .. 20 -- 10 to 20
put myRange.start --> 10
put myRange's end --> 20
add 15 to the end of myRange
put myRange --> 10 to 35

Use the is within operator to test if another value falls within the range:

Example:

set myRange to 10 .. 20
put 13 is within myRange --> True
put 18.975 is within myRange --> True
put 9.2 is within myRange --> False

A range is inclusive, that is, it includes both the start and end values. So any value between 10 and 20, including the values 10 and 20, falls within the example range:

Example:

set myRange to 10 .. 20
put 10 is within myRange --> True
put 20 is within myRange --> True

Use the is a range operator to test if a value is a range:

Example:

put myRange is a range --> True

Using a Range to Generate a List

Use a range as a sequence generator to automatically generate a sequence or list of values beginning with the start value of the range and continuing until its end value. The simplest way to cause a range to generate its values is to use the range in a context where a list is expected:

Example:

put item 5 of 10 to 20 --> 14
put the last 3 items of 100..200 by 2 --> [196,198,200]

If you specify a step by increment for the range, its absolute (positive) value is used when generating a sequence as the increment between sequential items in the list. If you do not specify a step by increment for the range, a value of 1 is assumed. Access or change the increment value of a range by using the step property of the range:

Example:

set the step of myRange to 3

To generate all of the values in the range at once, use the as list operator to request it as a list:

Example:

put 10.. 20 as a list --> [10,11,12,13,14,15,16,17,18,19,20]
put 10 to 20 by 2 as list --> [10,12,14,16,18,20]

Specify a range's endpoints in either order. For example as a range from 10 to 20 or from 20 to 10. For purposes of the is within operator the two are equivalent. The difference is the order in which values are generated if the range is treated as a list or used as an iterator.

Example:

put 20 .. 10 by 2 as a list --> [20,18,16,14,12,10]

Using the contains and is in Operators with Ranges

The contains and is in operators, when used with a range, treat the range as a list. In this case, a range only contains a value if that value is one of the distinct values generated by the range.

note

The is in and is within operators behave quite differently in this way:

set range to 10..20
put range contains 13 --> True
put range contains 13.5 --> False
put 13.5 is within range --> True (13.5 is between 10 and 20)
put 13.5 is in range --> False (it's not one of the values 10,11,12,13,14,15,16,17,18,19, or 20)

Date/Time Ranges

A date or time range works similarly to a numeric range. Both the start and end values must be valid as date or time values for it to be recognized as a time range:

Example:

set Q1 to "Jan 1" to "Mar 31"
put "Feb 3" is in Q1 --> True

When a time range is created without explicitly giving a step increment, the step value is assumed to be 1 day, 1 minute, or 1 second, depending on the start and end values:

  • If the start and end values are a day apart or more, a step value of 1 day is used.
  • If they are within 24 hours of each other but more than a minute apart, a step value of 1 minute will be used,
  • if the range is 60 seconds or less a step value of 1 second will be used.

For more natural readability of date/time ranges, specify the step value as a plural time unit like "days" instead of "1 day" or "minutes" instead of "1 minute":

Example:

set MondaysIn2009 to "2009-01-05" to "2009-12-31" by weeks

When a date/time range is accessed as a list, each value produced is a date/time value using the same format as the start value.

Example:

put item 33 of "Jan 1" to "March 31" --> "Feb 2"
put item 33 of "January 1" to "Mar 31" --> "February 2"

Character Ranges

A range can also specify a range of Unicode characters. One common use of character ranges is to specify the alphabet:

Example:

set alphabet to "a".."z"
set upperAndLowerLetters to "A".."Z" &&& "a".."z"
put "z" to "t" as list --> ["z","y","x","w","v","u","t"]

Using a Range as a Chunk Index

A range can be used to select certain characters, words, items, or other parts of a value:

Example:

put chars 1..5 of "abcdefgh" --> "abcde"
put chars 1..5 by 2 of "abcdefgh" --> "ace"
put items 2..6 by 2 of "a,b,c,d,e,f,g,h" --> "b,d,f"
put items 2..6 by 2 of [a,b,c,d,e,f,g,h] --> [b,d,f]
put chars 8..1 of "abcdefgh" --> "hgfedcba"
put chars 8..1 as list of "abcdefgh" --> [h,g,f,e,d,c,b,a]