qwebfub3i4u
qwebfub3i4u

Reputation: 319

Check for equivalence of string and symbol

I have a vector of symbols a_sym of length N_sym and a vector of strings a_str of length N_str

a_sym contains symbols at each index, such as :H₅B₂O₆⁻

a_str contains strings at each index, such as H₅B₂O₆⁻

I would like to check for equivalence of a_sym and a_str to see which index the equivalence occurs in each vector.

I have tried to implement a loop to check these two vectors:

E = zeros(Int64,N_sym)

for i in 1:N_str
    for ii in 1:N_sym
        if a_sym[ii] == a_str[i]
            E[ii] = i
        end
    end
end

Where E is my attempt to map equivalent indices, but my loop never detects the strings to be equivalent. How could this be remedied? (and perhaps simplified?)

For example:

a_sym = [:H₃BO₃ ,:H₄BO₄⁻ ,:Li⁺ ,:H₅B₂O₆⁻, :H₄B₃O₇⁻]

where N_sym would be 5, and:

a_str = ["O⁻","H₃BO₃","H₄BO₄⁻","H₅B₂O₆⁻","H₄B₃O₇⁻","H₃B₃O₆"]

where N_str would be 6. I require the loop to check both vectors and map the indices when there is equivalnce, for instance the index of H₃BO₃ in a_sym would be 1, and its index in a_str would be 2.

I expect a vector E = [2, 3, 0, 4, 5] which is filled with the indices of a_str, and 0 if a_str does not contain a match for a_sym

Upvotes: 1

Views: 381

Answers (1)

phipsgabler
phipsgabler

Reputation: 20950

Symbols and strings are never equivalent:

julia> :a == "a"
false

So you have to convert either to the other first. I would write your function as follows using the builtin findfirst:

julia> E = [findfirst(==(String(b)), a_str) for b in a_sym]
5-element Array{Union{Nothing, Int64},1}:
 2
 3
  nothing
 4
 5

(Although, as Przemislaw notes, converting the strings to symbols would likely be more efficient.)

nothing is what findfirst returns if it does not find anything. You can convert this to a default by broadcasting something:

julia> something.(E, 0)
5-element Array{Int64,1}:
 2
 3
 0
 4
 5

Upvotes: 4

Related Questions