indices

This page describes how to access the bounds and indices for arrays. See also Define a Generator for information about generators.

For an array a, the a.indices() operator results in a generator for the array's indices. For example, for one, two, and three dimensional arrays a, b, and c:

  for i <- b.indices() do
    println ("a[" i "]=" a[i])
  end
  for (i,j) <- b.indices() do
    println ("b[" i "," j "]=" b[i,j])
  end
  for (i,j,k) <- c.indices() do
    println ("c[" i "," j "," k "]=" c[i,j,k])
  end

Use seq(array.indices()) to get deterministic indexing.

Note: As per Trac #4, array.indices() only works if you use parentheses. The form

  for (i,j) <- b.indices do
    println ("b[" i "," j "]=" b[i,j])
  end

presented in the language specification does not work. When Trac #4 is fixed, the parenthesized form will no longer work.

bounds

a.bounds() yields a Range of the array bounds. You can use this to create specific generators or specific indexing. For example:

  (bl0,bl1) = b.bounds().lower()
  (bu0,bu1) = b.bounds().upper()
  println "nondeterministic order: for i <- bl0:bu0, j <- bl1:bu1 do"
  for i <- bl0:bu0, j <- bl1:bu1 do
     println ("b[" i "," j "]=" b[i,j])
  end
  println "deterministic order: for i <- seq(bl0:bu0), j <- sequential(bl1:bu1) do"
  for i <- seq(bl0:bu0), j <- sequential(bl1:bu1) do
     println ("b[" i "," j "]=" b[i,j])
  end
  println "nondeterministic order: for (i,j) <- b.indices() do"
  for (i,j) <- b.indices() do
     println ("b[" i "," j "]=" b[i,j])
  end
  println "deterministic order: for (i,j) <- seq(b.indices()) do"
  for (i,j) <- seq(b.indices()) do
     println ("b[" i "," j "]=" b[i,j])
  end

For a two dimensional array, the value returned by bounds() is a Range[\(ZZ32,ZZ32)\]. Actually, to be very specific it is a Tuple2Range[\ZZ32,ZZ32\].

The will also work

  for (i,j) <- b.bounds() do
     println ("b[" i "," j "]=" b[i,j])
  end
  for (i,j) <- seq(b.bounds()) do
     println ("b[" i "," j "]=" b[i,j])
  end

To access the upper bound for dimensions 0 and 1 of a two dimensional array b, use (u0,u1) = b.bounds().upper()

If you only want one, you can use _ to ignore the other one in the tuple binding: (u0,_) = b.bounds().upper()

indexValuePairs

array.indexValuePairs() is a generator for both the indices and the corresponding array value:

for (i,v) <- a.indexValuePairs() do
    println ("a[" i "]=" v)
end
for (ix,v) <- b.indexValuePairs() do
    (i,j) = ix
    println ("b[" i "," j "]=" v)
end

Sadly, you can't (yet) nest tuple bindings so it's actually a bit clunky for arrays of two or more dimensions. That is, you can't do

for ((i,j),v) <- b.indexValuePairs() do (* this does not yet work *)
    println ("b[" i "," j "]=" v)
end

In general, bounds yield a Range describing how big your array is, but indices returns a generator that actually follows the structure of the array itself. For example for a sparse matrix indices() yields only the defined indices whereas bounds() yields every index.