You need to execute some JSL more than once.
Use a for(...) or while(...) or one of the more exotic variations.
Cars = {"Ford", "Chevy", "Tesla"}; // a list
nCars = N Items( Cars );
// notice loop starts at one and <= counts to the end
For( iCar = 1, iCar <= nCars, iCar += 1,
car = Cars[iCar]; // JSL lists are 1-based
Write( "\!n", car, " has four wheels." );
);
for(i=2, i<= 3, i+=.1, print(i);); // 2, 2.1, ... 2.9 (but not 3.0)
write("\!nFinally ",i-3); // 8.88178419700125e-16
2for(i=0,i<=10,i++,
write(" ", 2 + i/10);
// 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3
);
2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 3authors = {"Margaret Mitchell", "J.D. Salinger", "Emily Brontë"};
iAuthor = 1;
While( iAuthor <= N Items( authors ),
Write( "\!n", authors[iAuthor], " wrote one novel" );
iAuthor += 1;
);
Margaret Mitchell wrote one novelanimals = {"octopus", "spider", "scorpion"};
While( N Items( animals ) > 0,
// RemoveFrom modifies the animals list
// and returns a list of (in this example)
// one item
animal = Remove From( animals, 1 );
// subscript the list to get just the animal
// name, without the curly braces for the list
Write( "\!n", animal[1], " has eight legs" );
);
octopus has eight legsFor( i = 1, i <= 10, i++,
If( i == 3, Continue() );
If( i == 7, Break() );
Write( " ", i ); // 1 2 4 5 6
);
1 2 4 5 6dt = Open( "$sample_data/big class.jmp" );
For Each Row(
If( Starts With( dt:name, "A" ),
Write( " ", dt:name ); // ALICE ALFRED AMY
)
);
ALICE ALFRED AMYdt = Open( "$sample_data/big class.jmp" );
hw = dt << New Column( "HW_Ratio", formula( height / weight ) );
dt << RunFormulas; // all 40 values are computed
dt << Sort(by (HW_Ratio), replaceTable); // tall enough for my weight?
s = Round(Sqrt( [1, 2, 3, 4, 5, 6, 7, 8, 9] ), 2);
write(s); // [1, 1.41, 1.73, 2, 2.24, 2.45, 2.65, 2.83, 3]
The matrix function Loc loops through a matrix and returns the locations of elements that Loc identifies. This is much faster than a for loop.s = Round(Sqrt( [1, 2, 3, 4, 5, 6, 7, 8, 9] ), 2);
write(Loc(s > 2)); // [5, 6, 7, 8, 9] (element 4 is equal)
Using matrix subscripting can reorganize matrices much faster than for loops.s = Round( Sqrt( [1, 2, 3, 4, 5, 6, 7, 8, 9] ), 2 );
s[Loc( s > 2 )] = -1;
Write( s ); // [1, 1.41, 1.73, 2, -1, -1, -1, -1, -1]
idx = 0; // not a recommended pattern!
mat = J( 2, 3, (idx += 1 ; Sqrt( idx )) );
Write( Round( mat, 1 ) ); // [1 1.4 1.7, 2 2.2 2.4]
The parallel assign function uses multiple threads to fill in an array. Unlike the J function 3rd argument, you can't depend on any particular ordering of the elements being calculated. Parallel assign tries to keep threads isolated from each other and really doesn't want its expression accessing global data.bigMat = J( 500, 500, . );
// these are global x and y values that are only copied into each thread, below.
x = 2;
yy = 3;
// x=x and y=yy is copying global values to local values of the same/similar name.
// bigMat[rr, cc] determines the array that is being filled in and the
// row and column names you'll use in the expression after the =.
// the if statement is an example expression, not terribly interesting but
// typical of the kind of thing parallel assign does well.
rc = Parallel Assign( {x = x, y = yy}, bigMat[rr, cc] = If( x == 2, rr * cc, y ) );
// Max dose NOT return an array, it returns the maximum value in the array.
// dividing by max scales the values from 0 to 1
bigMat = bigMat / Max( bigMat );
// new image expects values from 0 to 1
New Window( "demo", New Image( "rgb", {bigMat, 1 - bigMat, bigMat} ) );
text = // use the \[ and ]\ to escape the quotes in this text
"\[John Bartlett, who ran the University Book Store in Cambridge,
Massachusetts, was frequently asked for information on quotations and
he began a commonplace book of them for reference. In 1855, he
privately printed his compilation as A Collection of Familiar Quotations.
This first edition contained 258 pages of quotations by 169 authors,
chiefly the Bible, William Shakespeare, and the great English poets.
Bartlett wrote in the fourth edition that "it is not easy to determine in
all cases the degree of familiarity that may belong to phrases and
sentences which present themselves for admission; for what is familiar
to one class of readers may be quite new to another." - Wikipedia]\";
words = [=> 0]; // an associative array that defaults unknown keys to a value of 0
// this match repeats a pair of alternatives: a run of a-z or a run of NOT a-z.
// the runs of a-z are stored in an associative array
rc = Pat Match(
text,
Pat Repeat( // the loop starts here
(Pat Regex( "[a-zA-Z]+" ) >> word
+Pat Test( // insert word into words assoc array
words[Lowercase( word )] += 1; // this JSL is evaluated for each word
1; // the test must succeed for the pattern to continue
)) | Pat Regex( "[^a-zA-Z]+" ) // skip non-words
)
);
// make a table, load it from the words assoc array keys and values
dt = New Table( "word count",
New Column( "word", character, Set Values( words << getkeys ) ),
New Column( "count", Set Values( words << getvalues ) )
);
// sort by the count column
dt << sort( by( count ), order( descending ), replaceTable );
n = 0; // counter, just for this demo
dowork = Function( {},
Print( "hi", n );
n += 1;
If( n < 10,
Schedule( .5, dowork() );// half second from now, run me again
, // else
Schedule( 0, 0 ) << close; // no delay, no code
);
);
dowork(); // start the loop
// this tree walker looks for button boxes in a display
// box tree and prints the button name
treeWalker = Function( {box}, // parameter
{child = box << child}, // local variables
While( !Is Empty( child ),
If( child << classname == "ButtonBox",
Show( child << Get Button Name )
);
treeWalker( child ); // you could also use recurse(child)
child = child << sib;
)
);
x = V List Box(
H List Box( Button Box( "x" ), Button Box( "z" ) ),
Border Box( Button Box( "w" ) )
);
treeWalker( x ); // shows x, z, and w
Nesting loops can get quite slow. If you write an outer loop that examines every row in a table, and an inner loop that also examines every row in the table (perhaps looking for matches), JSL for loops will get painfully slow when the table has a 100,000 rows: the JSL in the inner loop will run 100,000 * 100,000 (10,000,000,000) times. If you can move this code into a matrix function, it will be faster, but you might need a different approach, sorting the table perhaps.
I've probably overlooked something.
http://www.jmp.com/support/help/Iterate.shtml
http://www.jmp.com/support/help/Conditional_and_Logical_Functions.shtml
A sliding window: a loop with a span and a step is an interesting instance. where the span >step. Are there any examples of such problem in JSL?
You can do that with for loops. Depending on the problem, you might find array subscripting faster and easier. An array or data table can be subscripted with a triple like
x[ start::stop::step ]
to return that slice of x. Or you can use
for( i = start, i <= stop, i+= step,
...statements separated by semicolons...
)
if you want to move the window, put an outer loop around it to adjust the start and stop values.
If you’re looking for a code snippet or design pattern that performs a common task for your JSL project, the JSL Cookbook is for you.
This knowledge base contains building blocks of JSL code that you can use to reduce the amount of coding you have to do yourself.
It's also a great place to learn from the experts how to use JSL in new ways, with best practices.