Skip to content

Commit

Permalink
use Some{T} instead of Nullable{T}
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed Oct 1, 2017
1 parent 6907913 commit 9b22856
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 13 deletions.
19 changes: 13 additions & 6 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2434,6 +2434,14 @@ symdiff(a, b, rest...) = symdiff(a, symdiff(b, rest...))

## replace/replace! ##


struct Some{T}
value::T
end

eltype(::Type{Some{T}}) where {T} = T
get(x::Some) = x.value

# NOTE: to implement replace! and replace for a new type T, it's enough to define:
# function _replace!(pred::Callable, new::Callable, A::T, count::Int)

Expand Down Expand Up @@ -2465,9 +2473,8 @@ replace!(A, old_new::Pair...; count::Integer=typemax(Int)) = _replace!(A, eltype
function _replace!(A, ::Type{K}, count::Integer, old_new #=::Pair...=#) where {K}
@inline function prednew(x)
for o_n in old_new
first(o_n) == x && return Nullable{K}(last(o_n))
first(o_n) == x && return Some{K}(last(o_n))
end
Nullable{K}()
end
_replace!(prednew, A, count)
end
Expand All @@ -2491,7 +2498,7 @@ julia> replace!(isodd, A, 0, count=2)
```
"""
replace!(pred::Callable, A, new; count::Integer=typemax(Int)) =
_replace!(x->Nullable(new, pred(x)), A, count)
_replace!(x -> if pred(x) Some(new) end, A, count)

"""
replace!(prednew::Function, A; [count::Integer])
Expand Down Expand Up @@ -2534,8 +2541,8 @@ function _replace!(prednew::Callable, A::AbstractArray, count::Int)
c = 0
@inbounds for i in eachindex(A)
y = prednew(A[i])
if !isnull(y)
A[i] = unsafe_get(y)
if y !== nothing
A[i] = get(y)
c += 1
c == count && break
end
Expand Down Expand Up @@ -2581,7 +2588,7 @@ julia> replace(isodd, [1, 2, 3, 1], 0, count=2)
```
"""
replace(pred::Callable, A, new; count::Integer=typemax(Int)) =
_replace!(x->Nullable(new, pred(x)), copy(A), count)
_replace!(x -> if pred(x) Some(new) end, copy(A), count)

"""
replace(prednew::Function, A; [count::Integer])
Expand Down
4 changes: 2 additions & 2 deletions base/set.jl
Original file line number Diff line number Diff line change
Expand Up @@ -490,8 +490,8 @@ function _replace!(prednew::Callable, A::Union{Associative,AbstractSet}, count::
c = 0
for x in A
y = prednew(x)
if !isnull(y)
push!(repl, x => unsafe_get(y))
if y !== nothing
push!(repl, x => get(y))
c += 1
c == count && break
end
Expand Down
12 changes: 7 additions & 5 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2238,10 +2238,12 @@ end
@test_throws BoundsError checkbounds(zeros(2,3,0), 2, 3)
end

maybe(v, p) = if p Some(v) end

@testset "replace! & replace" begin
a = [1, 2, 3, 1]
@test replace(x->Nullable(2x, iseven(x)), a) == [1, 4, 3, 1]
@test replace!(x->Nullable(2x, iseven(x)), a) === a
@test replace(x->maybe(2x, iseven(x)), a) == [1, 4, 3, 1]
@test replace!(x->maybe(2x, iseven(x)), a) === a
@test a == [1, 4, 3, 1]
@test replace(a, 1=>0) == [0, 4, 3, 0]
@test replace(a, 1=>0, count=1) == [0, 4, 3, 1]
Expand All @@ -2250,7 +2252,7 @@ end

d = Dict(1=>2, 3=>4)
@test replace(x->x.first > 2, d, 0=>0) == Dict(1=>2, 0=>0)
@test replace!(x->Nullable(x.first=>2*x.second, x.first > 2), d) === d
@test replace!(x->maybe(x.first=>2*x.second, x.first > 2), d) === d
@test d == Dict(1=>2, 3=>8)
@test replace(d, (3=>8)=>(0=>0)) == Dict(1=>2, 0=>0)
@test replace!(d, (3=>8)=>(2=>2)) === d
Expand All @@ -2259,8 +2261,8 @@ end
Dict(2=>2, 0=>0)]

s = Set([1, 2, 3])
@test replace(x->Nullable(2x, x>1), s) == Set([1, 4, 6])
@test replace(x->Nullable(2x, x>1), s, count=1) in [Set([1, 4, 3]), Set([1, 2, 6])]
@test replace(x->maybe(2x, x>1), s) == Set([1, 4, 6])
@test replace(x->maybe(2x, x>1), s, count=1) in [Set([1, 4, 3]), Set([1, 2, 6])]
@test replace(s, 1=>4) == Set([2, 3, 4])
@test replace!(s, 1=>2) === s
@test s == Set([2, 3])
Expand Down

0 comments on commit 9b22856

Please sign in to comment.