diff --git a/README.md b/README.md index 871d85d4a..2751b9d14 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,9 @@ Currently, the `@compat` macro supports the following syntaxes: ## New functions, macros, and methods +* `eachrow`, `eachcol`, and `eachslice` to iterate over first, second, or given dimension + of an array ([#29749]). + * `isnothing` for testing if a variable is equal to `nothing` ([#29674]). * `Compat.readline` with `keep` keyword argument ([#25646]) @@ -570,3 +573,4 @@ includes this fix. Find the minimum version from there. [#28850]: https://github.com/JuliaLang/julia/issues/28850 [#29259]: https://github.com/JuliaLang/julia/issues/29259 [#29674]: https://github.com/JuliaLang/julia/issues/29674 +[#29749]: https://github.com/JuliaLang/julia/issues/29749 diff --git a/src/Compat.jl b/src/Compat.jl index a4533bba4..1be0250ec 100644 --- a/src/Compat.jl +++ b/src/Compat.jl @@ -931,6 +931,21 @@ if VERSION < v"1.1.0-DEV.472" isnothing(::Nothing) = true end +# https://github.com/JuliaLang/julia/pull/29749 +@static if v"0.7" <= VERSION < v"1.1.0-DEV.792" + export eachrow, eachcol, eachslice + eachrow(A::AbstractVecOrMat) = (view(A, i, :) for i in axes(A, 1)) + eachcol(A::AbstractVecOrMat) = (view(A, :, i) for i in axes(A, 2)) + @inline function eachslice(A::AbstractArray; dims) + length(dims) == 1 || throw(ArgumentError("only single dimensions are supported")) + dim = first(dims) + dim <= ndims(A) || throw(DimensionMismatch("A doesn't have $dim dimensions")) + idx1, idx2 = ntuple(d->(:), dim-1), ntuple(d->(:), ndims(A)-dim) + return (view(A, idx1..., i, idx2...) for i in axes(A, dim)) + end +end + + @static if !isdefined(Base, :Some) import Base: promote_rule, convert diff --git a/test/runtests.jl b/test/runtests.jl index 9bea19403..b6a873768 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -30,6 +30,23 @@ end @test !isnothing(1) @test isnothing(nothing) +# https://github.com/JuliaLang/julia/pull/29749 +if VERSION >= v"0.7" + @testset "row/column/slice iterators" begin + # Simple ones + M = [1 2 3; 4 5 6; 7 8 9] + @test collect(eachrow(M)) == collect(eachslice(M, dims = 1)) == [[1, 2, 3], [4, 5, 6], [7, 8, 9]] + @test collect(eachcol(M)) == collect(eachslice(M, dims = 2)) == [[1, 4, 7], [2, 5, 8], [3, 6, 9]] + @test_throws DimensionMismatch eachslice(M, dims = 4) + + # Higher-dimensional case + M = reshape([(1:16)...], 2, 2, 2, 2) + @test_throws MethodError collect(eachrow(M)) + @test_throws MethodError collect(eachcol(M)) + @test collect(eachslice(M, dims = 1))[1][:, :, 1] == [1 5; 3 7] + end +end + # julia#26365 @test Compat.tr([1 2; 3 5]) == 6