dukereg
dukereg

Reputation: 722

How to treat String as Array/Vector in Julia

In Julia language, I want to use functions defined for Array{T,1} a.k.a. Vector{T} on a String, essentially treating it as Array{Char,1}.

An example of a function I would like to use:

julia> deleteat!("Hrello!",2)
ERROR: MethodError: no method matching deleteat!(::String, ::Int64)
Closest candidates are:
  deleteat!(::Array{T,1} where T, ::Integer) at array.jl:1177
  deleteat!(::Array{T,1} where T, ::Any) at array.jl:1214
  deleteat!(::BitArray{1}, ::Integer) at bitarray.jl:901
  ...
Stacktrace:
 [1] top-level scope at none:0

julia> deleteat!(['H','r','e','l','l','o','!'], 2)
6-element Array{Char,1}:
 'H'
 'e'
 'l'
 'l'
 'o'
 '!'

To be clear, I would like to start with a String and end up with a String, but use Array {Char,1} operations to alter the String.

Upvotes: 9

Views: 6842

Answers (2)

Julia Learner
Julia Learner

Reputation: 3032

Strings can be split into Arrays and then operated on by using the split function.

For example, this could be done for your code above like this:

julia> deleteat!(split("Hrello!", ""), 2)
6-element Array{SubString{String},1}:
 "H"
 "e"
 "l"
 "l"
 "o"
 "!"

Edit

Since providing the above code example using split, I did the following benchmark comparison of collect vs. split for this problem.

The result is that collect is much faster (> 10X) than split as shown below.

julia> VERSION
v"1.0.3"

julia> using BenchmarkTools

julia> @benchmark deleteat!(split("Hrello!", ""), 2)
BenchmarkTools.Trial:
  memory estimate:  1.42 KiB
  allocs estimate:  26
  --------------
  minimum time:     748.396 ns (0.00% GC)
  median time:      804.819 ns (0.00% GC)
  mean time:        1.067 μs (20.80% GC)
  maximum time:     465.984 μs (99.71% GC)
  --------------
  samples:          10000
  evals/sample:     144

julia> @benchmark deleteat!(collect("Hrello!"), 2)
BenchmarkTools.Trial:
  memory estimate:  112 bytes
  allocs estimate:  1
  --------------
  minimum time:     60.299 ns (0.00% GC)
  median time:      65.431 ns (0.00% GC)
  mean time:        89.189 ns (20.99% GC)
  maximum time:     66.601 μs (99.83% GC)
  --------------
  samples:          10000
  evals/sample:     1000

@Gnimuc's advice to try collect first is definitely backed up by this benchmark.

Upvotes: 6

Gnimuc
Gnimuc

Reputation: 8566

In Julia, one should always try collect firstly for getting a Vector from something else.

julia> deleteat!(collect("Hrello!"), 2)
6-element Array{Char,1}:
 'H'
 'e'
 'l'
 'l'
 'o'
 '!'

Upvotes: 9

Related Questions