1
struct EnumerableGroupBySimple{T,TKey,TS,SO,ES<:Function} <: Enumerable
2 23
    source::SO
3
    elementSelector::ES
4
end
5

6
struct Grouping{TKey,T} <: AbstractArray{T,1}
7 23
    _key::TKey
8
    elements::Array{T,1}
9
end
10

11 0
key(g::Grouping) = getfield(g, :_key)
12

13
struct GroupColumnArrayView{T,G,INDEX} <: AbstractVector{T}
14
    grouping::G
15
end
16

17
function Base.size(gcav::GroupColumnArrayView)
18 0
    return size(gcav.grouping)
19
end
20

21
function Base.getindex(gcav::GroupColumnArrayView{T,G,INDEX}, i::Int) where {T,G,INDEX}
22 0
    return getproperty(gcav.grouping[i],INDEX)
23
end
24

25 0
Base.IndexStyle(::Type{GroupColumnArrayView}) = IndexLinear()
26

27
function Base.getproperty(g::Grouping{TKey,T}, name::Symbol) where {TKey,T}
28
    
29 0
    return GroupColumnArrayView{fieldtype(T,name),Grouping{TKey,T},name}(g)
30
end
31

32 8
Base.size(A::Grouping{TKey,T}) where {TKey,T} = size(getfield(A, :elements))
33 8
Base.getindex(A::Grouping{TKey,T},i) where {TKey,T} = getfield(A, :elements)[i]
34 0
Base.length(A::Grouping{TKey,T}) where {TKey,T} = length(getfield(A, :elements))
35

36 0
Base.eltype(::Type{EnumerableGroupBySimple{T,TKey,TS,SO,ES}}) where {T,TKey,TS,SO,ES} = T
37

38
function groupby(source::Enumerable, f_elementSelector::Function, elementSelector::Expr)
39 23
    TS = eltype(source)
40 23
    TKey = Base._return_type(f_elementSelector, Tuple{TS,})
41

42
    SO = typeof(source)
43

44 23
    T = Grouping{TKey,TS}
45

46 23
    ES = typeof(f_elementSelector)
47

48 23
    return EnumerableGroupBySimple{T,TKey,TS,SO,ES}(source,f_elementSelector)
49
end
50

51
function Base.iterate(iter::EnumerableGroupBySimple{T,TKey,TS,SO,ES}) where {T,TKey,TS,SO,ES}
52 23
    result = OrderedDict{TKey,T}()
53 23
    for i in iter.source
54 20
        key = iter.elementSelector(i)
55 23
        if !haskey(result, key)
56 23
            result[key] = T(key,Array{TS}(undef, 0))
57
        end
58 23
        push!(getfield(result[key], :elements),i)
59
    end
60

61 20
    groups = collect(values(result))
62 23
    if length(groups)==0
63 0
        return nothing
64
    else
65 23
        return groups[1], (groups, 2)
66
    end
67
end
68

69
function Base.iterate(iter::EnumerableGroupBySimple{T,TKey,TS,SO,ES}, state) where {T,TKey,TS,SO,ES}
70 8
    if state[2]>length(state[1])
71 8
        return nothing
72
    else
73 8
        return state[1][state[2]], (state[1], state[2]+1)
74
    end
75
end
76

77
struct EnumerableGroupBy{T,TKey,TR,SO,ES<:Function,RS<:Function} <: Enumerable
78 23
    source::SO
79
    elementSelector::ES
80
    resultSelector::RS
81
end
82

83 0
Base.eltype(::Type{EnumerableGroupBy{T,TKey,TR,SO,ES, RS}}) where {T,TKey,TR,SO,ES,RS} = T
84

85
function groupby(source::Enumerable, f_elementSelector::Function, elementSelector::Expr, f_resultSelector::Function, resultSelector::Expr)
86 23
    TS = eltype(source)
87 23
    TKey = Base._return_type(f_elementSelector, Tuple{TS,})
88

89
    SO = typeof(source)
90

91 23
    TR = Base._return_type(f_resultSelector, Tuple{TS,})
92

93 23
    T = Grouping{TKey,TR}
94

95 23
    ES = typeof(f_elementSelector)
96 23
    RS = typeof(f_resultSelector)
97

98 23
    return EnumerableGroupBy{T,TKey,TR,SO,ES,RS}(source,f_elementSelector,f_resultSelector)
99
end
100

101
function Base.iterate(iter::EnumerableGroupBy{T,TKey,TR,SO,ES}) where {T,TKey,TR,SO,ES}
102 23
    result = OrderedDict{TKey,T}()
103 23
    for i in iter.source
104 20
        key = iter.elementSelector(i)
105 23
        if !haskey(result, key)
106 23
            result[key] = T(key,Array{TR}(undef,0))
107
        end
108 23
        push!(getfield(result[key], :elements),iter.resultSelector(i))
109
    end
110

111 20
    groups = collect(values(result))
112 23
    if length(groups)==0
113 0
        return nothing
114
    else
115 23
        return groups[1], (groups, 2)
116
    end
117
end
118

119
function Base.iterate(iter::EnumerableGroupBy{T,TKey,TR,SO,ES}, state) where {T,TKey,TR,SO,ES}
120 23
    if state[2]>length(state[1])
121 23
        return nothing
122
    else
123 23
        return state[1][state[2]], (state[1], state[2]+1)
124
    end
125
end

Read our documentation on viewing source code .

Loading