Parse vector from string


#1

I can parse(Int, „123“) but I cannot find a simple way to parse(Vector{Int}, „[1, 2, 3]”). Is there a “canned” solution?


#2

Broadcast the function.

x = ["1", "2", "3"]
y = parse.(Int64,x)

#3

If it is arbitrary julia code you can Meta.parse and eval it it but perhaps using something like JSON would be more suitable here?

If you just need to parse this exact format, splitting on the comma and broadcasting the parse would likely be the most efficient.


#4

Not necessarily sure if it is always faster to broadcast and do multiple calls to the parser instead of calling the parser a single time to instead parse a slightly larger string. Might be better sometimes to make single call.


#5

The julia source code parser and the parser that parses types like Ints are two completely different things.

julia> f(x) = parse(Int, x)
f (generic function with 1 method)

julia> @btime f("2")
  46.842 ns (0 allocations: 0 bytes)
2

julia> g(x) = Meta.parse(x)
f (generic function with 1 method)

julia> @btime g("2")
  19.187 μs (7 allocations: 208 bytes)
2

You should only use Meta.parse if you are parsing actual julia source code.


#6

As a simple solution in the past I’ve used:

@assert str[1] == '[' && str[end] == ']'
CSV.read(IOBuffer(str[2:prevind(str, end)]), header=false, transpose=true)

#7

Thank you - I was looking as CSC but didn’t see this trick.


#8

For curiosity, if I am given a strIng as Inshowed then how do Inconvert it into an array of strings?


#9

Sorry for misunderstanding earlier. Here’s something you can do if you really have to work with the string "[1, 2, 3]"

x = "[1, 2, 3]"
rr = r"([0-9])" # you can alter this to work with numbers with decimal places
matches = [parse(Int64,t.match) for t in eachmatch(rr, x)]

> 3-element Array{Int64,1}:
 1
 2
 3

#10

Very interesting, thank you. I’ll need to spend some time understanding this :slight_smile:


#11

Another workaround is to make it a full expression

vec = "[1, 2, 3]"
y = "y = "
t = y * vec
out = eval(parse(t))

#12

Definitely don’t do that. Using eval — and especially eval(parse(…)) — is a major red flag. It doesn’t work the way you expect within functions and it is prone to security issues and surprising bugs.