Skip to content

Commit

Permalink
Deprecate findin(a, b) in favor of find(occursin(b), a)
Browse files Browse the repository at this point in the history
  • Loading branch information
nalimilan committed Jan 4, 2018
1 parent 6cd052b commit e4a3a06
Show file tree
Hide file tree
Showing 12 changed files with 56 additions and 90 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,8 @@ Deprecated or removed

* `ismatch(regex, str)` has been deprecated in favor of `contains(str, regex)` ([#24673]).

* `findin(a, b)` has been deprecated in favor of `find(occursin(b), a)` ([#24673]).

Command-line option changes
---------------------------

Expand Down
4 changes: 2 additions & 2 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ get(A::AbstractArray, I::Dims, default) = checkbounds(Bool, A, I...) ? A[I...] :

function get!(X::AbstractVector{T}, A::AbstractVector, I::Union{AbstractRange,AbstractVector{Int}}, default::T) where T
# 1d is not linear indexing
ind = findin(I, indices1(A))
ind = find(occursin(indices1(A)), I)
X[ind] = A[I[ind]]
Xind = indices1(X)
X[first(Xind):first(ind)-1] = default
Expand All @@ -1064,7 +1064,7 @@ function get!(X::AbstractVector{T}, A::AbstractVector, I::Union{AbstractRange,Ab
end
function get!(X::AbstractArray{T}, A::AbstractArray, I::Union{AbstractRange,AbstractVector{Int}}, default::T) where T
# Linear indexing
ind = findin(I, 1:length(A))
ind = find(occursin(1:length(A)), I)
X[ind] = A[I[ind]]
X[1:first(ind)-1] = default
X[last(ind)+1:length(X)] = default
Expand Down
47 changes: 11 additions & 36 deletions base/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,7 @@ end

find(x::Bool) = x ? [1] : Vector{Int}()
find(testf::Function, x::Number) = !testf(x) ? Vector{Int}() : [1]
find(p::OccursIn, x::Number) = x in p.x ? Vector{Int}() : [1]

findn(A::AbstractVector) = find(A)

Expand Down Expand Up @@ -2052,7 +2053,7 @@ function _findin(a, b)
ind
end

# If two collections are already sorted, findin can be computed with
# If two collections are already sorted, _findin can be computed with
# a single traversal of the two collections. This is much faster than
# using a hash table (although it has the same complexity).
function _sortedfindin(v, w)
Expand Down Expand Up @@ -2094,42 +2095,16 @@ function _sortedfindin(v, w)
return out
end

"""
findin(a, b)
Return the indices of elements in collection `a` that appear in collection `b`.
# Examples
```jldoctest
julia> a = collect(1:3:15)
5-element Array{Int64,1}:
1
4
7
10
13
julia> b = collect(2:4:10)
3-element Array{Int64,1}:
2
6
10
julia> findin(a,b) # 10 is the only common element
1-element Array{Int64,1}:
4
```
"""
function findin(a::Array{<:Real}, b::Union{Array{<:Real},Real})
if issorted(a, Sort.Forward) && issorted(b, Sort.Forward)
return _sortedfindin(a, b)
function find(pred::OccursIn{<:Union{Array{<:Real},Real}}, x::Array{<:Real})
if issorted(x, Sort.Forward) && issorted(pred.x, Sort.Forward)
return _sortedfindin(x, pred.x)
else
return _findin(a, b)
return _findin(x, pred.x)
end
end
# issorted fails for some element types so the method above has to be restricted
# to element with isless/< defined.
findin(a, b) = _findin(a, b)
find(pred::OccursIn, x::Union{AbstractArray, Tuple}) = _findin(x, pred.x)

# Copying subregions
function indcopy(sz::Dims, I::Vector)
Expand All @@ -2138,8 +2113,8 @@ function indcopy(sz::Dims, I::Vector)
for i = n+1:length(sz)
s *= sz[i]
end
dst = eltype(I)[findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
src = eltype(I)[I[i][findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
dst = eltype(I)[_findin(I[i], i < n ? (1:sz[i]) : (1:s)) for i = 1:n]
src = eltype(I)[I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))] for i = 1:n]
dst, src
end

Expand All @@ -2149,8 +2124,8 @@ function indcopy(sz::Dims, I::Tuple{Vararg{RangeIndex}})
for i = n+1:length(sz)
s *= sz[i]
end
dst::typeof(I) = ntuple(i-> findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
src::typeof(I) = ntuple(i-> I[i][findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
dst::typeof(I) = ntuple(i-> _findin(I[i], i < n ? (1:sz[i]) : (1:s)), n)::typeof(I)
src::typeof(I) = ntuple(i-> I[i][_findin(I[i], i < n ? (1:sz[i]) : (1:s))], n)::typeof(I)
dst, src
end

Expand Down
2 changes: 2 additions & 0 deletions base/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3856,6 +3856,8 @@ end

@deprecate ismatch(r::Regex, s::AbstractString) contains(s, r)

@deprecate findin(a, b) find(occursin(b), a)

# END 0.7 deprecations

# BEGIN 1.0 deprecations
Expand Down
1 change: 0 additions & 1 deletion base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,6 @@ export
find,
findfirst,
findlast,
findin,
findmax,
findmin,
findmin!,
Expand Down
14 changes: 2 additions & 12 deletions base/range.jl
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ function intersect(r1::AbstractRange, r2::AbstractRange, r3::AbstractRange, r::A
i
end

# findin (the index of intersection)
# _findin (the index of intersection)
function _findin(r::AbstractRange{<:Integer}, span::AbstractUnitRange{<:Integer})
local ifirst
local ilast
Expand All @@ -724,17 +724,7 @@ function _findin(r::AbstractRange{<:Integer}, span::AbstractUnitRange{<:Integer}
ifirst = fr >= fspan ? 1 : length(r)+1
ilast = fr <= lspan ? length(r) : 0
end
ifirst, ilast
end

function findin(r::AbstractUnitRange{<:Integer}, span::AbstractUnitRange{<:Integer})
ifirst, ilast = _findin(r, span)
ifirst:ilast
end

function findin(r::AbstractRange{<:Integer}, span::AbstractUnitRange{<:Integer})
ifirst, ilast = _findin(r, span)
ifirst:1:ilast
r isa AbstractUnitRange ? (ifirst:ilast) : (ifirst:1:ilast)
end

## linear operations on ranges ##
Expand Down
2 changes: 2 additions & 0 deletions base/sparse/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,8 @@ function find(p::Function, S::SparseMatrixCSC)
I, J = _findn(p, S)
return Base._sub2ind(sz, I, J)
end
find(p::Base.OccursIn, x::SparseMatrixCSC) =
invoke(find, Tuple{Base.OccursIn, AbstractArray}, p, x)

findn(S::SparseMatrixCSC{Tv,Ti}) where {Tv,Ti} = _findn(x->true, S)

Expand Down
2 changes: 2 additions & 0 deletions base/sparse/sparsevector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,8 @@ function find(p::Function, x::SparseVector{<:Any,Ti}) where Ti

return I
end
find(p::Base.OccursIn, x::SparseVector{<:Any,Ti}) where {Ti} =
invoke(find, Tuple{Base.OccursIn, AbstractArray}, p, x)

function findnz(x::SparseVector{Tv,Ti}) where {Tv,Ti}
numnz = nnz(x)
Expand Down
1 change: 0 additions & 1 deletion doc/src/stdlib/collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ Fully implemented by:
Base.in
Base.eltype
Base.indexin
Base.findin
Base.unique
Base.unique!
Base.allunique
Expand Down
22 changes: 11 additions & 11 deletions stdlib/Dates/test/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ let
@test_throws ArgumentError minimum(dr)
@test_throws ArgumentError maximum(dr)
@test_throws BoundsError dr[1]
@test findin(dr, dr) == Int64[]
@test find(occursin(dr), dr) == Int64[]
@test [dr;] == T[]
@test isempty(reverse(dr))
@test length(reverse(dr)) == 0
Expand Down Expand Up @@ -58,7 +58,7 @@ let
if len < 10000
dr1 = [i for i in dr]
@test length(dr1) == len
@test findin(dr, dr) == [1:len;]
@test find(occursin(dr), dr) == [1:len;]
@test length([dr;]) == len
@test dr == dr1
@test hash(dr) == hash(dr1)
Expand All @@ -84,7 +84,7 @@ let
@test_throws ArgumentError minimum(dr)
@test_throws ArgumentError maximum(dr)
@test_throws BoundsError dr[1]
@test findin(dr, dr) == Int64[]
@test find(occursin(dr), dr) == Int64[]
@test [dr;] == T[]
@test isempty(reverse(dr))
@test length(reverse(dr)) == 0
Expand Down Expand Up @@ -116,7 +116,7 @@ let
if len < 10000
dr1 = [i for i in dr]
@test length(dr1) == len
@test findin(dr, dr) == [1:len;]
@test find(occursin(dr), dr) == [1:len;]
@test length([dr;]) == len
@test dr == dr1
@test hash(dr) == hash(dr1)
Expand Down Expand Up @@ -144,7 +144,7 @@ let
@test_throws ArgumentError minimum(dr)
@test_throws ArgumentError maximum(dr)
@test_throws BoundsError dr[1]
@test findin(dr, dr) == Int64[]
@test find(occursin(dr), dr) == Int64[]
@test [dr;] == T[]
@test isempty(reverse(dr))
@test length(reverse(dr)) == 0
Expand Down Expand Up @@ -176,7 +176,7 @@ let
if len < 10000
dr1 = [i for i in dr]
@test length(dr1) == len
@test findin(dr, dr) == [1:len;]
@test find(occursin(dr), dr) == [1:len;]
@test length([dr;]) == len
@test dr == dr1
@test hash(dr) == hash(dr1)
Expand All @@ -202,7 +202,7 @@ let
@test_throws ArgumentError minimum(dr)
@test_throws ArgumentError maximum(dr)
@test_throws BoundsError dr[1]
@test findin(dr, dr) == Int64[]
@test find(occursin(dr), dr) == Int64[]
@test [dr;] == T[]
@test isempty(reverse(dr))
@test length(reverse(dr)) == 0
Expand Down Expand Up @@ -234,7 +234,7 @@ let
if len < 10000
dr1 = [i for i in dr]
@test length(dr1) == len
@test findin(dr, dr) == [1:len;]
@test find(occursin(dr), dr) == [1:len;]
@test length([dr;]) == len
@test dr == dr1
@test hash(dr) == hash(dr1)
Expand Down Expand Up @@ -293,7 +293,7 @@ drs2 = map(x->Dates.Date(first(x)):step(x):Dates.Date(last(x)), drs)
@test map(length, drs) == map(x->size(x)[1], drs)
@test map(length, drs) == map(x->length(Dates.Date(first(x)):step(x):Dates.Date(last(x))), drs)
@test map(length, drs) == map(x->length(reverse(x)), drs)
@test all(x->findin(x, x)==[1:length(x);], drs[1:4])
@test all(x->find(occursin(x), x)==[1:length(x);], drs[1:4])
@test isempty(dr2)
@test all(x->reverse(x) == range(last(x), -step(x), length(x)), drs)
@test all(x->minimum(x) == (step(x) < zero(step(x)) ? last(x) : first(x)), drs[4:end])
Expand Down Expand Up @@ -371,7 +371,7 @@ drs = Any[dr, dr1, dr2, dr3, dr4, dr5, dr6, dr7, dr8, dr9, dr10,
dr11, dr12, dr13, dr14, dr15, dr16, dr17, dr18, dr19, dr20]

@test map(length, drs) == map(x->size(x)[1], drs)
@test all(x->findin(x, x) == [1:length(x);], drs[1:4])
@test all(x->find(occursin(x), x) == [1:length(x);], drs[1:4])
@test isempty(dr2)
@test all(x->reverse(x) == last(x): - step(x):first(x), drs)
@test all(x->minimum(x) == (step(x) < zero(step(x)) ? last(x) : first(x)), drs[4:end])
Expand Down Expand Up @@ -557,7 +557,7 @@ drs = Any[dr, dr1, dr2, dr3, dr8, dr9, dr10,
dr11, dr12, dr13, dr14, dr15, dr16, dr17, dr18, dr19, dr20]

@test map(length, drs) == map(x->size(x)[1], drs)
@test all(x->findin(x, x) == [1:length(x);], drs[1:4])
@test all(x->find(occursin(x), x) == [1:length(x);], drs[1:4])
@test isempty(dr2)
@test all(x->reverse(x) == last(x): - step(x):first(x), drs)
@test all(x->minimum(x) == (step(x) < zero(step(x)) ? last(x) : first(x)), drs[4:end])
Expand Down
28 changes: 14 additions & 14 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -265,30 +265,30 @@ end

a = [3, 5, -7, 6]
b = [4, 6, 2, -7, 1]
ind = findin(a, b)
ind = find(occursin(b), a)
@test ind == [3,4]
@test findin(a, Int[]) == Int[]
@test findin(Int[], a) == Int[]
@test find(occursin(Int[]), a) == Int[]
@test find(occursin(a), Int[]) == Int[]

a = [1,2,3,4,5]
b = [2,3,4,6]
@test findin(a, b) == [2,3,4]
@test findin(b, a) == [1,2,3]
@test findin(a, Int[]) == Int[]
@test findin(Int[], a) == Int[]
@test find(occursin(b), a) == [2,3,4]
@test find(occursin(a), b) == [1,2,3]
@test find(occursin(Int[]), a) == Int[]
@test find(occursin(a), Int[]) == Int[]

a = collect(1:3:15)
b = collect(2:4:10)
@test findin(a, b) == [4]
@test findin([a[1:4]; a[4:end]], b) == [4,5]
@test find(occursin(b), a) == [4]
@test find(occursin(b), [a[1:4]; a[4:end]]) == [4,5]

@test findin([1.0, NaN, 2.0], NaN) == [2]
@test findin([1.0, 2.0, NaN], NaN) == [3]
@test find(occursin(NaN), [1.0, NaN, 2.0]) == [2]
@test find(occursin(NaN), [1.0, 2.0, NaN]) == [3]

@testset "findin for uncomparable element types" begin
@testset "find(::OccursIn, b) for uncomparable element types" begin
a = [1 + 1im, 1 - 1im]
@test findin(a, 1 + 1im) == [1]
@test findin(a, a) == [1,2]
@test find(occursin(1 + 1im), a) == [1]
@test find(occursin(a), a) == [1,2]
end

rt = Base.return_types(setindex!, Tuple{Array{Int32, 3}, UInt8, Vector{Int}, Int16, UnitRange{Int}})
Expand Down
21 changes: 8 additions & 13 deletions test/ranges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -249,21 +249,15 @@ end
@test length(0.0:-0.5) == 0
@test length(1:2:0) == 0
end
@testset "findin" begin
@test findin([5.2, 3.3], 3:20) == findin([5.2, 3.3], collect(3:20))
@testset "find(::OccursIn, ::Array)" begin
@test find(occursin(3:20), [5.2, 3.3]) == find(occursin(collect(3:20)), [5.2, 3.3])

let span = 5:20,
r = -7:3:42
@test findin(r, span) == 5:10
@test find(occursin(span), r) == 5:10
r = 15:-2:-38
@test findin(r, span) == 1:6
@test find(occursin(span), r) == 1:6
end
#@test isempty(findin(5+0*(1:6), 2:4))
#@test findin(5+0*(1:6), 2:5) == 1:6
#@test findin(5+0*(1:6), 2:7) == 1:6
#@test findin(5+0*(1:6), 5:7) == 1:6
#@test isempty(findin(5+0*(1:6), 6:7))
#@test findin(5+0*(1:6), 5:5) == 1:6
end
@testset "reverse" begin
@test reverse(reverse(1:10)) == 1:10
Expand Down Expand Up @@ -1115,15 +1109,16 @@ end
@test intersect(r, Base.OneTo(2)) == Base.OneTo(2)
@test intersect(r, 0:5) == 1:3
@test intersect(r, 2) === intersect(2, r) === 2:2
@test findin(r, r) === findin(r, 1:length(r)) === findin(1:length(r), r) === 1:length(r)
@test find(occursin(r), r) === find(occursin(1:length(r)), r) ===
find(occursin(r), 1:length(r)) === 1:length(r)
io = IOBuffer()
show(io, r)
str = String(take!(io))
@test str == "Base.OneTo(3)"
end
let r = Base.OneTo(7)
@test findin(r, 2:(length(r) - 1)) === 2:(length(r) - 1)
@test findin(2:(length(r) - 1), r) === 1:(length(r) - 2)
@test find(occursin(2:(length(r) - 1)), r) === 2:(length(r) - 1)
@test find(occursin(r), 2:(length(r) - 1)) === 1:(length(r) - 2)
end
end

Expand Down

0 comments on commit e4a3a06

Please sign in to comment.