Skip to content

Commit 46b8611

Browse files
authored
Merge pull request #23 from queryverse/unique-command
Unique command
2 parents c125e43 + 3078559 commit 46b8611

6 files changed

Lines changed: 83 additions & 0 deletions

File tree

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# QueryOperators.jl v0.6.0 Release Notes
2+
* Add unique command
3+
14
# QueryOperators.jl v0.5.2 Release Notes
25
* Various bug fixes
36
* Some new features for NamedTupleUtilities

src/QueryOperators.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ include("enumerable/enumerable_defaultifempty.jl")
2222
include("enumerable/enumerable_count.jl")
2323
include("enumerable/enumerable_take.jl")
2424
include("enumerable/enumerable_drop.jl")
25+
include("enumerable/enumerable_unique.jl")
2526
include("enumerable/show.jl")
2627

2728
include("source_iterable.jl")
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
struct EnumerableUnique{T,TKEY,S,Q<:Function} <: Enumerable
2+
source::S
3+
f::Q
4+
end
5+
6+
function unique(source::Enumerable, f::Function, f_expr::Expr)
7+
T = eltype(source)
8+
S = typeof(source)
9+
TKEY = Base._return_type(f, Tuple{T,})
10+
return EnumerableUnique{T,TKEY,S,typeof(f)}(source, f)
11+
end
12+
13+
Base.eltype(::Type{EnumerableUnique{T,TKEY,S,Q}}) where {T,TKEY,S,Q} = T
14+
15+
function Base.iterate(iter::EnumerableUnique{T,TKEY,S,Q}) where {T,TKEY,S,Q}
16+
ret = iterate(iter.source)
17+
18+
ret===nothing && return nothing
19+
20+
observed_keys = Set{TKEY}()
21+
22+
first_element = ret[1]
23+
source_state = ret[2]
24+
25+
key_first_element = iter.f(first_element)
26+
27+
push!(observed_keys, key_first_element)
28+
29+
return first_element, (observed_keys=observed_keys, source_state=source_state)
30+
end
31+
32+
function Base.iterate(iter::EnumerableUnique{T,TKEY,S,Q}, state) where {T,TKEY,S,Q}
33+
ret = iterate(iter.source, state.source_state)
34+
35+
ret===nothing && return nothing
36+
37+
while true
38+
current_element = ret[1]
39+
key_current_element=iter.f(current_element)
40+
if key_current_element in state.observed_keys
41+
ret = iterate(iter.source, ret[2])
42+
ret===nothing && return nothing
43+
else
44+
push!(state.observed_keys, key_current_element)
45+
46+
return current_element, (observed_keys=state.observed_keys, source_state=ret[2])
47+
end
48+
end
49+
end

src/operators.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,10 @@ function drop end
116116
macro drop(source, n)
117117
:(drop($(esc(source)), $(esc(n))))
118118
end
119+
120+
function unique end
121+
122+
macro unique(source, f)
123+
q = Expr(:quote, f)
124+
:(unique($(esc(source)), $(esc(f)), $(esc(q))))
125+
end

test/runtests.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ a │ b │ c
149149

150150
end
151151

152+
include("test_enumerable_unique.jl")
153+
152154
include("test_namedtupleutilities.jl")
153155

154156
end

test/test_enumerable_unique.jl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Test
2+
3+
@testset "unique" begin
4+
5+
source_1 = [1,2,2,3,3,3,4]
6+
enum = QueryOperators.query(source_1)
7+
8+
@test collect(QueryOperators.@unique(enum, i->i)) == [1,2,3,4]
9+
10+
source_1 = [1,2,3,4]
11+
enum = QueryOperators.query(source_1)
12+
13+
@test collect(QueryOperators.@unique(enum, i->i)) == [1,2,3,4]
14+
15+
source_1 = [1,-1,2,3,4]
16+
enum = QueryOperators.query(source_1)
17+
18+
@test collect(QueryOperators.@unique(enum, i->abs(i))) == [1,2,3,4]
19+
20+
21+
end

0 commit comments

Comments
 (0)