1
struct EnumerableOrderby{T,S,KS<:Function,TKS} <: Enumerable
2 23
    source::S
3
    keySelector::KS
4
    descending::Bool
5
end
6

7 0
Base.IteratorSize(::Type{EnumerableOrderby{T,S,KS,TKS}}) where {T,S,KS,TKS} = haslength(S)
8

9 0
Base.eltype(::Type{EnumerableOrderby{T,S,KS,TKS}}) where {T,S,KS,TKS} = T
10

11 18
Base.length(iter::EnumerableOrderby{T,S,KS,TKS}) where {T,S,KS,TKS} = length(iter.source)
12

13
function orderby(source::Enumerable, f::Function, f_expr::Expr)
14 23
    T = eltype(source)
15 23
    TKS = Base._return_type(f, Tuple{T,})
16

17 23
    KS = typeof(f)
18

19 23
    return EnumerableOrderby{T,typeof(source), KS,TKS}(source, f, false)
20
end
21

22
function orderby_descending(source::Enumerable, f::Function, f_expr::Expr)
23 23
    T = eltype(source)
24 23
    TKS = Base._return_type(f, Tuple{T,})
25

26 23
    KS = typeof(f)
27

28 23
    return EnumerableOrderby{T,typeof(source),KS,TKS}(source, f, true)
29
end
30

31
function Base.iterate(iter::EnumerableOrderby{T,S,KS,TKS}) where {T,S,KS,TKS}
32 23
    rows = (Base.IteratorSize(typeof(iter)) isa Base.HasLength || Base.IteratorSize(typeof(iter)) isa Base.HasShape) ? length(iter) : 0
33

34 23
    elements = Array{T}(undef, rows)
35

36
    if Base.IteratorSize(typeof(iter)) isa Base.HasLength || Base.IteratorSize(typeof(iter)) isa Base.HasShape
37 23
        for i in enumerate(iter.source)
38 23
            elements[i[1]] = i[2]
39
        end
40
    else
41 23
        for i in iter.source
42 23
            push!(elements, i)
43
        end
44
    end
45

46 23
    if length(elements)==0
47 0
        return nothing
48
    end
49

50 18
    sort!(elements, by=iter.keySelector, rev=iter.descending)
51

52 23
    return elements[1], (elements, 2)
53
end
54

55
function Base.iterate(iter::EnumerableOrderby{T,S,KS,TKS}, state) where {T,S,KS,TKS}
56 10
    if state[2]>length(state[1])
57 10
        return nothing
58
    else
59 10
        return state[1][state[2]], (state[1], state[2]+1)
60
    end
61
end
62

63
struct EnumerableThenBy{T,S,KS<:Function,TKS} <: Enumerable
64
    source::S
65
    keySelector::KS
66
    descending::Bool
67
end
68

69 0
Base.eltype(::Type{EnumerableThenBy{T,S,KS,TKS}}) where {T,S,KS,TKS} = T
70

71 0
Base.length(iter::EnumerableThenBy{T,S,KS,TKS}) where {T,S,KS,TKS} = length(iter.source)
72

73
function thenby(source::Enumerable, f::Function, f_expr::Expr)
74 0
    T = eltype(source)
75 0
    TKS = Base._return_type(f, Tuple{T,})
76 0
    KS = typeof(f)
77 0
    return EnumerableThenBy{T,typeof(source),KS,TKS}(source, f, false)
78
end
79

80
function thenby_descending(source::Enumerable, f::Function, f_expr::Expr)
81 0
    T = eltype(source)
82 0
    TKS = Base._return_type(f, Tuple{T,})
83 0
    KS = typeof(f)
84 0
    return EnumerableThenBy{T,typeof(source),KS,TKS}(source, f, true)
85
end
86

87
function Base.iterate(iter::EnumerableThenBy{T,S,KS,TKS}) where {T,S,KS,TKS}
88
    # Find start of ordering sequence
89 0
    source = iter.source
90 0
    keySelectors = [source.keySelector,iter.keySelector]
91 0
    directions = [source.descending, iter.descending]
92 0
    while !isa(source, EnumerableOrderby)
93 0
        source = source.source
94 0
        insert!(keySelectors,1,source.keySelector)
95 0
        insert!(directions,1,source.descending)
96
    end
97 0
    keySelector = element->[i(element) for i in keySelectors]
98

99 0
    lt = (t1,t2) -> begin
100 0
        n1, n2 = length(t1), length(t2)
101 0
        for i = 1:min(n1, n2)
102 0
            a, b = t1[i], t2[i]
103 0
            descending = directions[i]
104 0
            if !isequal(a, b)
105 0
                return descending ? !isless(a, b) : isless(a, b)
106
            end
107
        end
108 0
        return n1 < n2
109
    end
110

111 0
    rows = (Base.IteratorSize(typeof(iter)) isa Base.HasLength || Base.IteratorSize(typeof(iter)) isa Base.HasShape) ? length(iter) : 0
112

113 0
    elements = Array{T}(undef, rows)
114

115 0
    if (Base.IteratorSize(typeof(iter)) isa Base.HasLength || Base.IteratorSize(typeof(iter)) isa Base.HasShape)
116 0
        for i in enumerate(iter.source)
117 0
            elements[i[1]] = i[2]
118
        end        
119
    else
120 0
        for i in iter.source
121 0
            push!(elements, i)
122
        end
123
    end
124

125 0
    if length(elements)==0
126 0
        return nothing
127
    end
128

129 0
    sort!(elements, by=keySelector, lt=lt)
130

131 0
    return elements[1], (elements, 2)
132
end
133

134
function Base.iterate(iter::EnumerableThenBy{T,S,KS,TKS}, state) where {T,S,KS,TKS}
135 0
    if state[2]>length(state[1])
136 0
        return nothing
137
    else
138 0
        return state[1][state[2]], (state[1], state[2]+1)
139
    end
140
end

Read our documentation on viewing source code .

Loading