For scientific applications, it is often useful to have arrays whose indices may start anywhere. Let's try to define a 1D array with this property, as an example of implementing a new type.
I want
a = IndexedArray([3,4,5], -7) # starting from -7
a[-7]
Exercise: What structure should it have?
In [1]:
In [1]:
type IndexedArray
data::Vector{Float64}
low_index::Integer
end
Exercise: Write a function that calculates the correct index.
We calculate the correct index once and for all:
In [2]:
reindex(a::IndexedArray, i) = i - a.low_index + 1
Out[2]:
In [3]:
getindex(a::IndexedArray, i) = a.data[reindex(a, i)]
Out[3]:
In [ ]:
In [4]:
v = IndexedArray([3, 4, 5], -3)
Out[4]:
In [5]:
v[-3]
Out[5]:
In [12]:
v[-2]
Out[12]:
In [6]:
v[-1]
Out[6]:
In [7]:
v[0]
In [8]:
v[-1] = 10
Many operations already work:
In [13]:
v[-3:-2]
Out[13]:
But others don't yet:
In [14]:
v[-3] = 10
In [9]:
setindex!(a::IndexedArray, x, i) = a.data[reindex(a, i)] = x
Out[9]:
In [10]:
v[-3] = 10
Out[10]:
In [12]:
v
Out[12]:
In [20]:
v[-3] = 10
Out[20]:
In [21]:
v
Out[21]:
In [13]:
for i in v
println(i)
end
To define iteration for our new type, we need to define the start, next and done functions.
To see how to do so, the easiest thing is to copy some pre-existing code!
In [13]:
methods(start)
Out[13]:
Let's pick the one for an abstract array. This is what we need to implement:
In [18]:
# start(a::AbstractArray) = 1
# next(a::AbstractArray,i) = (a[i],i+1)
# done(a::AbstractArray,i) = (i > length(a))
First, we must, as the error message says, explicitly import the functions from Base in order to extend them:
In [21]:
import Base: start, next, done
In [22]:
start(a::IndexedArray) = a.low_index
next(a::IndexedArray,i) = (a[i],i+1)
done(a::IndexedArray,i) = (i > a.low_index + length(a) - 1)
Out[22]:
In [23]:
v
Out[23]:
In [24]:
for i in v
println(i)
end
In [25]:
length(a::IndexedArray) = length(a.data)
Out[25]:
In [24]:
import Base.length
In [25]:
length(a::IndexedArray) = length(a.data)
Out[25]:
In [32]:
for i in v
println(i)
end
In [26]:
v
Out[26]:
In [27]:
v + v
In [ ]: