asymptote: Slices

 
 6.12.1 Slices
 -------------
 
 Asymptote allows a section of an array to be addressed as a slice using
 a Python-like syntax.  If 'A' is an array, the expression 'A[m:n]'
 returns a new array consisting of the elements of 'A' with indices from
 'm' up to but not including 'n'.  For example,
 int[] x={0,1,2,3,4,5,6,7,8,9};
 int[] y=x[2:6];  // y={2,3,4,5};
 int[] z=x[5:10]; // z={5,6,7,8,9};
 
    If the left index is omitted, it is taken be '0'.  If the right index
 is omitted it is taken to be the length of the array.  If both are
 omitted, the slice then goes from the start of the array to the end,
 producing a non-cyclic deep copy of the array.  For example:
 int[] x={0,1,2,3,4,5,6,7,8,9};
 int[] y=x[:4];  // y={0,1,2,3}
 int[] z=x[5:];  // z={5,6,7,8,9}
 int[] w=x[:];   // w={0,1,2,3,4,5,6,7,8,9}, distinct from array x.
 
    If A is a non-cyclic array, it is illegal to use negative values for
 either of the indices.  If the indices exceed the length of the array,
 however, they are politely truncated to that length.
 
    For cyclic arrays, the slice 'A[m:n]' still consists of the cells
 with indices in the set ['m','n'), but now negative values and values
 beyond the length of the array are allowed.  The indices simply wrap
 around.  For example:
 
 int[] x={0,1,2,3,4,5,6,7,8,9};
 x.cyclic=true;
 int[] y=x[8:15];  // y={8,9,0,1,2,3,4}.
 int[] z=x[-5:5];  // z={5,6,7,8,9,0,1,2,3,4}
 int[] w=x[-3:17]; // w={7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6}
 
    Notice that with cyclic arrays, it is possible to include the same
 element of the original array multiple times within a slice.  Regardless
 of the original array, arrays produced by slices are always non-cyclic.
 
    If the left and right indices of a slice are the same, the result is
 an empty array.  If the array being sliced is empty, the result is an
 empty array.  Any slice with a left index greater than its right index
 will yield an error.
 
    Slices can also be assigned to, changing the value of the original
 array.  If the array being assigned to the slice has a different length
 than the slice itself, elements will be inserted or removed from the
 array to accommodate it.  For instance:
 string[] toppings={"mayo", "salt", "ham", "lettuce"};
 toppings[0:2]=new string[] {"mustard", "pepper"};
     // Now toppings={"mustard", "pepper", "ham", "lettuce"}
 toppings[2:3]=new string[] {"turkey", "bacon" };
     // Now toppings={"mustard", "pepper", "turkey", "bacon", "lettuce"}
 toppings[0:3]=new string[] {"tomato"};
     // Now toppings={"tomato", "bacon", "lettuce"}
 
    If an array is assigned to a slice of itself, a copy of the original
 array is assigned to the slice.  That is, code such as 'x[m:n]=x' is
 equivalent to 'x[m:n]=copy(x)'.  One can use the shorthand 'x[m:m]=y' to
 insert the contents of the array 'y' into the array 'x' starting at the
 location just before 'x[m]'.
 
    For a cyclic array, a slice is bridging if it addresses cells up to
 the end of the array and then continues on to address cells at the start
 of the array.  For instance, if 'A' is a cyclic array of length 10,
 'A[8:12]', 'A[-3:1]', and 'A[5:25]' are bridging slices whereas
 'A[3:7]', 'A[7:10]', 'A[-3:0]' and 'A[103:107]' are not.  Bridging
 slices can only be assigned to if the number of elements in the slice is
 exactly equal to the number of elements we are assigning to it.
 Otherwise, there is no clear way to decide which of the new entries
 should be 'A[0]' and an error is reported.  Non-bridging slices may be
 assigned an array of any length.
 
    For a cyclic array 'A' an expression of the form
 'A[A.length:A.length]' is equivalent to the expression 'A[0:0]' and so
 assigning to this slice will insert values at the start of the array.
 'A.append()' can be used to insert values at the end of the array.
 
    It is illegal to assign to a slice of a cyclic array that repeats any
 of the cells.