# Slices

A sequence of consecutive elements may be selected by giving the starting and ending element numbers. For example:

            y = {"fred", "george", "mary"}
            y = y[1..2]                     -- y is now {"fred", "george"}.
            x = {1,1,2,2,2,1,1,1}
            y = x[3..5]             -- y is now {2,2,2}
            y = x[3..3]             -- y is now {2}
            y = x[3..2]             -- y is now {}

The last line evaluates to the length-0 sequence {}.
We can also use slices for overwriting portions of variables.

            x = {1,1,2,2,2,1,1,1}
            x[3..5] = {9,9,9}       -- x is now {1,1,9,9,9,1,1,1}
            x[3..5] = 8             -- x is now {1,1,8,8,8,1,1,1}
            y = {0, "Phix", 1, 1}
            z = y[2][2..3]          -- z is now "hi"
            y[2][2..4]="ete"        -- y is now {0,"Pete",1,1}

In general, a variable name can be followed by 0 or more subscripts, optionally followed by at most 1 slice. A slice operation cannot be followed by any further subcripting or slicing (though if absolutely necessary, you can force the issue by adding extra parenthesis).
We need to be a bit more precise in defining the rules for empty slices. Consider a slice s[i..j] where s is of length n. A slice from i to j, where j = i-1 and i >= 1 produces the empty sequence, even if i = n+1. Thus 1..0 and n+1..n and everything in between are legal (empty) slices. Empty slices are quite useful in many algorithms. A slice from i to j where j < i-1 is illegal, i.e. "reverse" slices such as s[5..3] are not allowed.
It is also perfectly legal to use negative indexes for the start and end of a slice, though it is left as an exercise for the reader to determine what is and what is not a valid empty slice should you mix positive and negative start and end points, however I will mention that it is, perhaps surprisingly, perfectly legal to use s[0..-1] with the same meaning as s[length(s)+1..length(s)], aka s[$+1..$], all three of course being "" or {}, and similarly s[-length(s)..-length(s)-1] is exactly the same as s[1..0]. A much better example of a proper (all-negative) slice is:

            filename = "filename.txt"
            extension = filename[-4..-1]        -- extension is now ".txt"

The $ shorthand and `to` keyword can also be used in slices, for example:

            filename = "filename.txt"
            k = find('.',filename)
            extension = filename[k+1..$]        -- extension is now "txt"
            extension = filename[k+1 to $]      -- (same as above, if you prefer it)
            filename = filename[1..k-1]         -- filename is now "filename"

If you replace a slice with an atom, it replaces each element, for example:

            s = "food"
            s[2..3] = 'e'       -- s is now "feed"

Phix also allows variable length slice substitution, for example:

            s = "food"
            s[2..3] = "e"       -- s is now "fed" (contrast with the previous example)
            s[2..1] = "ill"     -- s is now "filled"

Note that performing thousands of such length-altering substitutions on a very long string/sequence can often be performed much faster by chopping it up into thousands of pieces and reassembling everything once at the end. (See the library routine substitute() and its implementation in builtins\substitute.e) It should be obvious that moving the last element and many things before it, each thousands of times, is inevitably going to be exponentially slower than moving them just twice. However for a single substitution (or thousands of non-length-altering substitutions) the obvious neat one-liner is also the fastest possible method.
Compatibility Note: variable length slice substitution is not supported by Euphoria, which must use say `s = s[1..1]&"e"&s[4..4]`, as explained next.