From 9fb0dae75420b96a154e0e2ff7225e800242df52 Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Sun, 14 Jun 2015 19:56:42 +0200 Subject: [PATCH] Add eachindex() fallback for arbitrary iterables Especially useful for strings, but also for any iterable which would use unevenly spaced or non-integer indices. Fixes #11649. --- base/iterator.jl | 12 ++++++++++++ doc/stdlib/arrays.rst | 4 +++- test/arrayops.jl | 1 + test/strings.jl | 4 ++++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/base/iterator.jl b/base/iterator.jl index 6b1bc4a6c2b27..f7915e3990461 100644 --- a/base/iterator.jl +++ b/base/iterator.jl @@ -2,6 +2,18 @@ isempty(itr) = done(itr, start(itr)) +# eachindex + +immutable EachIndex{I} + itr::I +end +eachindex(itr) = EachIndex(itr) + +length(e::EachIndex) = length(e.itr) +start(e::EachIndex) = start(e.itr) +next(e::EachIndex, state) = (state, next(e.itr, state)[2]) +done(e::EachIndex, state) = done(e.itr, state) + # enumerate immutable Enumerate{I} diff --git a/doc/stdlib/arrays.rst b/doc/stdlib/arrays.rst index 4cde84a8baf3a..8308029eef067 100644 --- a/doc/stdlib/arrays.rst +++ b/doc/stdlib/arrays.rst @@ -33,7 +33,9 @@ Basic functions .. function:: eachindex(A...) - Creates an iterable object for visiting each index of an AbstractArray ``A`` in an efficient manner. For array types that have opted into fast linear indexing (like ``Array``), this is simply the range ``1:length(A)``. For other array types, this returns a specialized Cartesian range to efficiently index into the array with indices specified for every dimension. Example for a sparse 2-d array:: + Creates an iterable object for visiting each index of an AbstractArray ``A`` in an efficient manner. For array types that have opted into fast linear indexing (like ``Array``), this is simply the range ``1:length(A)``. For other array types, this returns a specialized Cartesian range to efficiently index into the array with indices specified for every dimension. For other iterables, including strings, this returns an iterator object supporting arbitrary index types (e.g. unevenly spaced or non-integer indices). + + Example for a sparse 2-d array:: julia> A = sprand(2, 3, 0.5) 2x3 sparse matrix with 4 Float64 entries: diff --git a/test/arrayops.jl b/test/arrayops.jl index be01e2b0979c7..f1afc12b62d30 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -812,6 +812,7 @@ let a36 = boo32_64() end @test isequal([1,2,3], [a for (a,b) in enumerate(2:4)]) @test isequal([2,3,4], [b for (a,b) in enumerate(2:4)]) +@test isequal([1,2,3], [i for i in eachindex(2:4)]) @test_throws DomainError (10.^[-1])[1] == 0.1 @test (10.^[-1.])[1] == 0.1 diff --git a/test/strings.jl b/test/strings.jl index 20ca448f55e17..4fce934c0c029 100644 --- a/test/strings.jl +++ b/test/strings.jl @@ -1732,3 +1732,7 @@ d = UTF32String(c) c[1] = 'A' @test d=="A" +# iteration +@test [c for c in "ḟøøƀäṙ"] == ['ḟ', 'ø', 'ø', 'ƀ', 'ä', 'ṙ'] +@test [i for i in eachindex("ḟøøƀäṙ")] == [1, 4, 6, 8, 10, 12] +@test [x for x in enumerate("ḟøøƀäṙ")] == [(1, 'ḟ'), (2, 'ø'), (3, 'ø'), (4, 'ƀ'), (5, 'ä'), (6, 'ṙ')]