From 71427122131676abda90ce2e02e3beeef8938e11 Mon Sep 17 00:00:00 2001 From: Stephan Hilb Date: Tue, 11 Sep 2018 16:40:27 +0200 Subject: [PATCH] base/sort: add sort! for multidimensional arrays (#28902) --- base/sort.jl | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ test/arrayops.jl | 5 +++++ 2 files changed, 54 insertions(+) diff --git a/base/sort.jl b/base/sort.jl index e04829a3191c4..dd55a0835a56f 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -938,6 +938,8 @@ Sort a multidimensional array `A` along the given dimension. See [`sort!`](@ref) for a description of possible keyword arguments. +To sort slices of an array, refer to [`sortslices`](@ref). + # Examples ```jldoctest julia> A = [4 3; 1 2] @@ -987,6 +989,53 @@ end Av end +""" + sort!(A; dims::Integer, alg::Algorithm=defalg(v), lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward) + +Sort the multidimensional array `A` along dimension `dims`. +See [`sort!`](@ref) for a description of possible keyword arguments. + +To sort slices of an array, refer to [`sortslices`](@ref). + +# Examples +```jldoctest +julia> A = [4 3; 1 2] +2×2 Array{Int64,2}: + 4 3 + 1 2 + +julia> sort!(A, dims = 1); A +2×2 Array{Int64,2}: + 1 2 + 4 3 + +julia> sort!(A, dims = 2); A +2×2 Array{Int64,2}: + 1 2 + 3 4 +``` +""" +function sort!(A::AbstractArray; + dims::Integer, + alg::Algorithm=defalg(A), + lt=isless, + by=identity, + rev::Union{Bool,Nothing}=nothing, + order::Ordering=Forward) + ordr = ord(lt, by, rev, order) + nd = ndims(A) + k = dims + + 1 <= k <= nd || throw(ArgumentError("dimension out of range")) + + remdims = ntuple(i -> i == k ? 1 : size(A, i), nd) + for idx in CartesianIndices(remdims) + Av = view(A, ntuple(i -> i == k ? Colon() : idx[i], nd)...) + sort!(Av, alg, ordr) + end + A +end + ## fast clever sorting for floats ## module Float diff --git a/test/arrayops.jl b/test/arrayops.jl index 3edc8516838eb..20a0fb26e3963 100644 --- a/test/arrayops.jl +++ b/test/arrayops.jl @@ -1199,11 +1199,13 @@ end @test issorted(as[:,1]) @test issorted(as[:,2]) @test issorted(as[:,3]) + @test sort!(copy(a), dims=1) == as as = sort(a, dims=2) @test issorted(as[1,:]) @test issorted(as[2,:]) @test issorted(as[3,:]) + @test sort!(copy(a), dims=2) == as local b = rand(21,21,2) @@ -1212,15 +1214,18 @@ end @test issorted(bs[:,i,1]) @test issorted(bs[:,i,2]) end + @test sort!(copy(b), dims=1) == bs bs = sort(b, dims=2) for i in 1:21 @test issorted(bs[i,:,1]) @test issorted(bs[i,:,2]) end + @test sort!(copy(b), dims=2) == bs bs = sort(b, dims=3) @test all(bs[:,:,1] .<= bs[:,:,2]) + @test sort!(copy(b), dims=3) == bs end @testset "higher dimensional sortslices" begin