Sequences 2
Primer
Starting with two sequences:
sequence x = {1,2,3,4,5} sequence y = {600,700,800}
A tremendous wealth of sequence manipulations are possible:
Operation | Example | Check |
---|---|---|
index |
? x[1] -- is 1 ? x[$] -- is 5 |
minimum index is 1 maximum index is length |
slice |
? x[1..3] -- is {1,2,3} ? x[2..4] -- is {2,3,4} ? x[3..$] -- is {3.4.5} |
|
concatenate |
? x & y -- is {1,2,3,4,5,600,700,800} |
lengths are added |
splice |
? splice(x,y,2} -- is {1,600,700,800,3,4,5} |
lengths are added |
remove |
? remove(x,2) -- is {1,3,4,5} ? remove(x,2,4) -- is {1,5} |
length - length_slice |
replace |
? replace(x,y,2) -- is {1,600,700,800,3,4,5} ? replace(x,y,2,4) -- is {1,600,700,800,5} |
length - length_slice + length_new |
prepend |
? prepend(x, y ) -- is {{600,700,800},1,2,3,4,5} |
length + 1 |
insert |
? insert(x,y,2} -- is {1,{600,700,800},2,3,4,5} |
length + 1 |
append |
? append(x,y) -- is {1,2,3,4,5,{600,700,800}} |
length + 1 |
Operators
All of the relational, logical, and arithmetic operators, as well as the math routines described in Language Reference, can be applied to sequences as well as to single numbers (atoms).
Euphoria has very consistent syntax. So, once some property or feature of the language has been defined, it continues to be defined for all cases.
When applied to a sequence, a unary (one operand) operator is actually applied to each element in the sequence to yield a sequence of results of the same length. If one of these elements is itself a sequence then the same rule is applied again recursively:.
x = -{1, 2, 3, {4, 5}} -- x is {-1, -2, -3, {-4, -5}}
The new sequence is of the exact same shape as the original. The negation operator ultimately has applied to every atom--the basic fundamental definition of negation has not changed, even when applied to a sequence.
If a binary (two-operand) operator has operands which are both sequences then the two sequences must be of the same length. The binary operation is then applied to corresponding elements taken from the two sequences to get a sequence of results:
x = {5, 6, 7, 8} + {10, 10, 20, 100} -- x is {15, 16, 27, 108} x = {{1, 2, 3}, {4, 5, 6}} + {-1, 0, 1} -- ERROR: 2 != 3 -- but x = { {1, 2, 3} + {-1, 0, 1}, {4, 5, 6} + {-1, 0, 1} } -- CORRECT -- x is {{0, 2, 4}, {3, 5, 7}}
If a binary operator has one operand which is a sequence while the other is a single number (atom) then the single number is effectively repeated to form a sequence of equal length to the sequence operand. The rules for operating on two sequences then apply:
y = {4, 5, 6} w = 5 * y -- w is {20, 25, 30} -- effectively the same as -- { 5, 5, 5 } * { 4, 5, 6 } -- { 5*4, 5*5, 5*6 } -- { 20, 25, 30 }
Since multiplication is a binary operation between two atoms, even when a sequence is involved, the fundamental behavior of multiplication does not change.
Binary operators, regardless of their action, continue to work just as they did before:
y = {4, 5, 6} x = {1, 2, 3} z = x + y -- z is {5, 7, 9} z = x < y -- z is {1, 1, 1} w = {{1, 2}, {3, 4}, {5}} w = w * y -- w is {{4, 8}, {15, 20}, {30}} w = {1, 0, 0, 1} and {1, 1, 1, 0} -- {1, 0, 0, 0} w = not {1, 5, -2, 0, 0} -- w is {0, 0, 0, 1, 1}
The next example should only appear strange at first glance:
w = {1, 2, 3} = {1, 2, 4} -- w is {1, 1, 0} -- the first '=' is assignment, and -- the second '=' is a relational operator that tests equality
By now it should make sense that it is not possible to compare two strings (or any two sequences) using the = operator. The '=' operator always compares two atoms!
? "APPLE" = "PEACH" --> { 0, 0, 0, 0, 0 } -- no single true or false result
It may be tempting, but wrong, to try this:
if "APPLE" = "ORANGE" then -- ERROR!
The value for an if ... then condition must be an atom--the fundamental requirement for a conditional never changes. When '=' is applied as a comparison between sequences, it is never possible to produce an atom value.
To make things worse, "APPLE" has a length of 5, and "ORANGE" has a length of 6. It is not even possible to begin a comparison between these two strings.
Instead you should use the equal() built-in function:
if equal("APPLE", "ORANGE") then -- CORRECT
In general, you can do relational comparisons using the compare() built-in function:
if compare("APPLE", "ORANGE") = 0 then -- CORRECT
You can use compare() for other comparisons as well:
if compare("APPLE", "ORANGE") < 0 then -- CORRECT -- enter here if "APPLE" is less than "ORANGE" (TRUE)
Especially useful is the idiom compare(x, "") = 1 to determine whether x is a non empty sequence. compare(x, "") = -1 would test for x being an atom, but atom(x) = 1 does the same faster and is clearer to read.
Not Categorized, Please Help
|