-
Notifications
You must be signed in to change notification settings - Fork 244
/
accumulator.jl
58 lines (38 loc) · 1.46 KB
/
accumulator.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# A counter type
type Accumulator{T, V<:Number}
map::Dict{T,V}
end
## constructors
Accumulator{T,V<:Number}(::Type{T}, ::Type{V}) = Accumulator{T,V}(Dict{T,V}())
counter(T::Type) = Accumulator(T,Int)
Accumulator{T,V<:Number}(dct::Dict{T,V}) = Accumulator{T,V}(copy(dct))
counter{T}(dct::Dict{T,Int}) = Accumulator{T,Int}(copy(dct))
function counter{T}(seq::AbstractArray{T})
ct = counter(T)
for x in seq
push!(ct, x)
end
return ct
end
copy{T,V<:Number}(ct::Accumulator{T,V}) = Accumulator{T,V}(copy(ct.map))
length(a::Accumulator) = length(a.map)
## retrieval
getindex{T,V}(ct::Accumulator{T,V}, x::T) = get(ct.map, x, zero(V))
haskey{T,V}(ct::Accumulator{T,V}, x::T) = haskey(ct.map, x)
keys(ct::Accumulator) = keys(ct.map)
## iteration
start(ct::Accumulator) = start(ct.map)
next(ct::Accumulator, state) = next(ct.map, state)
done(ct::Accumulator, state) = done(ct.map, state)
# manipulation
push!{T,V<:Number}(ct::Accumulator{T,V}, x::T, a::V) = (ct.map[x] = ct[x] + a)
push!{T,V<:Number,V2<:Number}(ct::Accumulator{T,V}, x::T, a::V2) = push!(ct, x, convert(V,a))
push!{T,V<:Number}(ct::Accumulator{T,V}, x::T) = push!(ct, x, one(V))
function push!{T,V<:Number,V2<:Number}(ct::Accumulator{T,V}, r::Accumulator{T,V2})
for (x::T, v::V2) in r
push!(ct, x, v)
end
ct
end
pop!{T,V<:Number}(ct::Accumulator{T,V}, x::T) = pop!(ct.map, x)
merge{T,V<:Number}(ct1::Accumulator{T,V}, ct2::Accumulator{T,V}) = push!(copy(ct1), ct2)