Skip to content

Commit 94c1c15

Browse files
committed
update sort
1 parent cda9e30 commit 94c1c15

File tree

1 file changed

+23
-37
lines changed

1 file changed

+23
-37
lines changed

src/TupleTools.jl

Lines changed: 23 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -234,56 +234,42 @@ end
234234
235235
Sorts the tuple `t`.
236236
"""
237-
@inline sort(t::Tuple; lt=isless, by=identity, rev::Bool=false) = _sort(t, lt, by, rev)
237+
sort(t::Tuple; lt=isless, by=identity, rev::Bool=false) = _sort(t, lt, by, rev)
238238
@inline function _sort(t::Tuple, lt=isless, by=identity, rev::Bool=false)
239-
i = 1
240-
if rev
241-
for k = 2:length(t)
242-
if lt(by(t[i]), by(t[k]))
243-
i = k
244-
end
245-
end
239+
t1, t2 = _split(t)
240+
t1s = _sort(t1, lt, by, rev)
241+
t2s = _sort(t2, lt, by, rev)
242+
return _merge(t1s, t2s, lt, by, rev)
243+
end
244+
_sort(t::Tuple{Any}, lt=isless, by=identity, rev::Bool=false) = t
245+
_sort(t::Tuple{}, lt=isless, by=identity, rev::Bool=false) = t
246+
247+
function _split(t::NTuple{N}) where N
248+
M = N>>1
249+
ntuple(i->t[i], M), ntuple(i->t[i+M], N-M)
250+
end
251+
252+
@inline function _merge(t1::Tuple, t2::Tuple, lt, by, rev)
253+
if lt(by(first(t1)), by(first(t2))) || rev
254+
return (first(t1), _merge(tail(t1), t2, lt, by, rev)...)
246255
else
247-
for k = 2:length(t)
248-
if lt(by(t[k]), by(t[i]))
249-
i = k
250-
end
251-
end
256+
return (first(t2), _merge(t1, tail(t2), lt, by, rev)...)
252257
end
253-
return (t[i], _sort(_deleteat(t, i), lt, by, rev)...)
254258
end
255-
@inline _sort(t::Tuple{Any}, lt=isless, by=identity, rev::Bool=false) = t
256-
@inline _sort(t::Tuple{}, lt=isless, by=identity, rev::Bool=false) = t
259+
_merge(t1::Tuple{}, t2::Tuple, lt, by, rev) = t2
260+
_merge(t1::Tuple, t2::Tuple{}, lt, by, rev) = t1
261+
257262

258263
"""
259264
sortperm(t::Tuple; lt=isless, by=identity, rev::Bool=false) -> ::Tuple
260265
261266
262267
Computes a tuple that contains the permutation required to sort `t`.
263268
"""
264-
@inline sortperm(t::Tuple; lt=isless, by=identity, rev::Bool=false) = _sortperm(t, lt, by, rev)
269+
sortperm(t::Tuple; lt=isless, by=identity, rev::Bool=false) = _sortperm(t, lt, by, rev)
265270
@inline function _sortperm(t::Tuple, lt=isless, by=identity, rev::Bool=false)
266-
i::Int = 1
267-
if rev
268-
for k = 2:length(t)
269-
if lt(by(t[i]), by(t[k]))
270-
i = k
271-
end
272-
end
273-
else
274-
for k = 2:length(t)
275-
if lt(by(t[k]), by(t[i]))
276-
i = k
277-
end
278-
end
279-
end
280-
r = _sortperm(_deleteat(t, i), lt, by, rev)
281-
return (i, _ishift(r, i, +1)...)
271+
_sort(ntuple(identity, length(t)), lt, i->by(getindex(t, i)), rev)
282272
end
283-
@inline _sortperm(t::Tuple{Any}, lt=isless, by=identity, rev::Bool=false) = (1,)
284-
@inline _sortperm(t::Tuple{}, lt=isless, by=identity, rev::Bool=false) = ()
285-
286-
_ishift(t::Tuple{Vararg{Int}}, i::Int, s::Int) = map(n->(n < i ? n : n+s), t)
287273

288274
"""
289275
getindices(t::Tuple, I::Tuple{Vararg{Int}}) -> ::Tuple

0 commit comments

Comments
 (0)