Parse vector from string

A simple proposal:

str = "[1, 2, 3]" 
parse.(Int, split(chop(str, head=1),','))
6 Likes

I ran into the same need as OP and @rafael.guerra’s suggestion worked perfectly.

julia> abc[1]
"[2.507612778, 2.507612778, 2.507612778, 0.563968079, 0.488410684, 0.488410684]"

julia> parse.(Float64,split(chop(abc[1],head=1),","))
6-element Vector{Float64}:
 2.507612778
 2.507612778
 2.507612778
 0.563968079
 0.488410684
 0.488410684
using DelimitedFiles
@views vec(readdlm(IOBuffer(str[2:end-1]), ','))

may do less allocations? The CSV package is probably(?) even faster, but I find it a bit non-intuitive to use if you don’t want a DataFrame:

using CSV
@views [row[1] for row in CSV.File(IOBuffer(str[2:end-1]), header=0, transpose=true)]

Update: @btime says that parse.(Float64, split(chop(str, head=1),',')), or ≈equivalently @views parse.(Float64, split(str[2:end-1],',')), is actually the fastest for str = "[2.507612778, 2.507612778, 2.507612778, 0.563968079, 0.488410684, 0.488410684]". CSV.jl is really optimized only for large files, I’m guessing — both it and DelimitedFiles currently allocate like crazy for parsing tiny strings like this.

Thanks for the update. And I see that (forehead slap) str[2:end-1] is a bit more direct than chop(str, head=1). I guess I could have figured that out with a bit of thought…

Note that chop returns a SubString whereas str[2:end-1] returns a copy, unless you use @views (or similar) for the latter.

(str[2:end-1] also only works if the characters are ASCII, whereas chop can also handle arbitrary Unicode characters. For example, "[α]"[2:end-1] fails because end-1 is not a valid index.)