Skip to content

Commit a989d36

Browse files
committed
Merge pull request #10902 from JuliaLang/teh/indexingdoc
Add more documentation on array iteration
2 parents 3dbc828 + 7ae6f16 commit a989d36

File tree

2 files changed

+67
-16
lines changed

2 files changed

+67
-16
lines changed

NEWS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ Library improvements
168168

169169
* Data-structure processing
170170

171-
* New multidimensional iterators and index types for efficient iteration over `AbstractArray`s ([#8432]).
171+
* New multidimensional iterators and index types for efficient iteration over `AbstractArray`s. Array iteration should generally be written as `for i in eachindex(A) ... end` rather than `for i = 1:length(A) ... end`. ([#8432])
172172

173173
* New implementation of SubArrays with substantial performance and functionality improvements ([#8501]).
174174

doc/manual/arrays.rst

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,18 @@ Arrays
4040
Basic Functions
4141
---------------
4242

43-
============================ ==============================================================================
44-
Function Description
45-
============================ ==============================================================================
46-
:func:`eltype(A) <eltype>` the type of the elements contained in A
47-
:func:`length(A) <length>` the number of elements in A
48-
:func:`ndims(A) <ndims>` the number of dimensions of A
49-
:func:`size(A) <size>` a tuple containing the dimensions of A
50-
:func:`size(A,n) <size>` the size of A in a particular dimension
51-
:func:`stride(A,k) <stride>` the stride (linear index distance between adjacent elements) along dimension k
52-
:func:`strides(A) <strides>` a tuple of the strides in each dimension
53-
============================ ==============================================================================
43+
================================ ==============================================================================
44+
Function Description
45+
================================ ==============================================================================
46+
:func:`eltype(A) <eltype>` the type of the elements contained in ``A``
47+
:func:`length(A) <length>` the number of elements in ``A``
48+
:func:`ndims(A) <ndims>` the number of dimensions of ``A``
49+
:func:`size(A) <size>` a tuple containing the dimensions of ``A``
50+
:func:`size(A,n) <size>` the size of ``A`` in a particular dimension
51+
:func:`eachindex(A) <eachindex>` an efficient iterator for visiting each position in ``A``
52+
:func:`stride(A,k) <stride>` the stride (linear index distance between adjacent elements) along dimension ``k``
53+
:func:`strides(A) <strides>` a tuple of the strides in each dimension
54+
================================ ==============================================================================
5455

5556
Construction and Initialization
5657
-------------------------------
@@ -218,16 +219,16 @@ The general syntax for indexing into an n-dimensional array A is::
218219

219220
X = A[I_1, I_2, ..., I_n]
220221

221-
where each I\_k may be:
222+
where each ``I_k`` may be:
222223

223224
1. A scalar integer
224225
2. A ``Range`` of the form ``:``, ``a:b``, or ``a:b:c``
225226
3. An arbitrary integer vector, including the empty vector ``[]``
226227
4. A boolean vector
227228

228-
The result X generally has dimensions
229+
The result ``X`` generally has dimensions
229230
``(length(I_1), length(I_2), ..., length(I_n))``, with location
230-
``(i_1, i_2, ..., i_n)`` of X containing the value
231+
``(i_1, i_2, ..., i_n)`` of ``X`` containing the value
231232
``A[I_1[i_1], I_2[i_2], ..., I_n[i_n]]``. Trailing dimensions
232233
indexed with scalars are dropped. For example, the dimensions of ``A[I, 1]`` will be
233234
``(length(I),)``. Boolean vectors are first transformed with ``find``; the size of
@@ -236,6 +237,13 @@ As a special part of this syntax, the ``end`` keyword may be used to represent t
236237
index of each dimension within the indexing brackets, as determined by the size of the
237238
innermost array being indexed.
238239

240+
Alternatively, single elements of a multidimensional array can be indexed as
241+
::
242+
x = A[I]
243+
244+
where ``I`` is a ``CartesianIndex``, effectively an ``n``-tuple of integers.
245+
See :ref:`man-array-iteration` below.
246+
239247
Indexing syntax is equivalent to a call to ``getindex``::
240248

241249
X = getindex(A, I_1, I_2, ..., I_n)
@@ -275,7 +283,7 @@ The general syntax for assigning values in an n-dimensional array A is::
275283

276284
A[I_1, I_2, ..., I_n] = X
277285

278-
where each I\_k may be:
286+
where each ``I_k`` may be:
279287

280288
1. A scalar value
281289
2. A ``Range`` of the form ``:``, ``a:b``, or ``a:b:c``
@@ -313,6 +321,49 @@ Example:
313321
2 -1 -1
314322
3 6 9
315323

324+
.. _man-array-iteration:
325+
326+
Iteration
327+
---------
328+
329+
The recommended ways to iterate over a whole array are
330+
::
331+
332+
for a in A
333+
# Do something with the element a
334+
end
335+
336+
for i in eachindex(A)
337+
# Do something with i and/or A[i]
338+
end
339+
340+
The first construct is used when you need the value, but not index, of each element. In the second construct, ``i`` will be an ``Int`` if ``A`` is an array
341+
type with fast linear indexing; otherwise, it will be a ``CartesianIndex``::
342+
343+
A = rand(4,3)
344+
B = sub(A, 1:3, 2:3)
345+
julia> for i in eachindex(B)
346+
@show i
347+
end
348+
i = Base.IteratorsMD.CartesianIndex_2(1,1)
349+
i = Base.IteratorsMD.CartesianIndex_2(2,1)
350+
i = Base.IteratorsMD.CartesianIndex_2(3,1)
351+
i = Base.IteratorsMD.CartesianIndex_2(1,2)
352+
i = Base.IteratorsMD.CartesianIndex_2(2,2)
353+
i = Base.IteratorsMD.CartesianIndex_2(3,2)
354+
355+
In contrast with ``for i = 1:length(A)``, iterating with ``eachindex`` provides an efficient way to iterate over any array type.
356+
357+
Array traits
358+
------------
359+
360+
If you write a custom ``AbstractArray`` type, you can specify that it has fast linear indexing using
361+
::
362+
363+
Base.linearindexing{T<:MyArray}(::Type{T}) = LinearFast()
364+
365+
This setting will cause ``eachindex`` iteration over a ``MyArray`` to use integers. If you don't specify this trait, the default value ``LinearSlow()`` is used.
366+
316367
Vectorized Operators and Functions
317368
----------------------------------
318369

0 commit comments

Comments
 (0)