1
|
|
struct EnumerableGroupBySimple{T,TKey,TS,SO,ES<:Function} <: Enumerable
|
2
|
47
|
source::SO
|
3
|
|
elementSelector::ES
|
4
|
|
end
|
5
|
|
|
6
|
|
struct Grouping{TKey,T} <: AbstractArray{T,1}
|
7
|
47
|
_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
|
17
|
Base.size(A::Grouping{TKey,T}) where {TKey,T} = size(getfield(A, :elements))
|
33
|
17
|
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
|
47
|
TS = eltype(source)
|
40
|
47
|
TKey = Base._return_type(f_elementSelector, Tuple{TS,})
|
41
|
|
|
42
|
|
SO = typeof(source)
|
43
|
|
|
44
|
47
|
T = Grouping{TKey,TS}
|
45
|
|
|
46
|
47
|
ES = typeof(f_elementSelector)
|
47
|
|
|
48
|
47
|
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
|
47
|
result = OrderedDict{TKey,T}()
|
53
|
47
|
for i in iter.source
|
54
|
39
|
key = iter.elementSelector(i)
|
55
|
47
|
if !haskey(result, key)
|
56
|
47
|
result[key] = T(key,Array{TS}(undef, 0))
|
57
|
|
end
|
58
|
47
|
push!(getfield(result[key], :elements),i)
|
59
|
|
end
|
60
|
|
|
61
|
39
|
groups = collect(values(result))
|
62
|
47
|
if length(groups)==0
|
63
|
0
|
return nothing
|
64
|
|
else
|
65
|
47
|
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
|
17
|
if state[2]>length(state[1])
|
71
|
17
|
return nothing
|
72
|
|
else
|
73
|
17
|
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
|
47
|
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
|
47
|
TS = eltype(source)
|
87
|
47
|
TKey = Base._return_type(f_elementSelector, Tuple{TS,})
|
88
|
|
|
89
|
|
SO = typeof(source)
|
90
|
|
|
91
|
47
|
TR = Base._return_type(f_resultSelector, Tuple{TS,})
|
92
|
|
|
93
|
47
|
T = Grouping{TKey,TR}
|
94
|
|
|
95
|
47
|
ES = typeof(f_elementSelector)
|
96
|
47
|
RS = typeof(f_resultSelector)
|
97
|
|
|
98
|
47
|
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
|
47
|
result = OrderedDict{TKey,T}()
|
103
|
47
|
for i in iter.source
|
104
|
39
|
key = iter.elementSelector(i)
|
105
|
47
|
if !haskey(result, key)
|
106
|
47
|
result[key] = T(key,Array{TR}(undef,0))
|
107
|
|
end
|
108
|
47
|
push!(getfield(result[key], :elements),iter.resultSelector(i))
|
109
|
|
end
|
110
|
|
|
111
|
39
|
groups = collect(values(result))
|
112
|
47
|
if length(groups)==0
|
113
|
0
|
return nothing
|
114
|
|
else
|
115
|
47
|
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
|
47
|
if state[2]>length(state[1])
|
121
|
47
|
return nothing
|
122
|
|
else
|
123
|
47
|
return state[1][state[2]], (state[1], state[2]+1)
|
124
|
|
end
|
125
|
|
end
|