What's the reasonable way to replace a character in a String in a specified position? Well, maybe replace is no possible safely, but is this the best we can get?
new = old[1:pos-1]*'C'*[pos+1:end]
Maybe with @views
Accessors.jl has functionality for it:
julia> using Accessors
julia> @set "helio"[4] = 'l'
"hello"
Nice, but it just seems to be doing the same I do (so not worth the dependency):
julia> s = "abcdefghijklmnop"
"abcdefghijklmnop"
julia> g(s) = @set s[10] = 'C'
g (generic function with 1 method)
julia> f(s) = s[1:9]*'C'*s[11:end]
f (generic function with 1 method)
julia> @b f(s)
85.958 ns (3.03 allocs: 104.664 bytes)
julia> @b g(s)
85.509 ns (3.02 allocs: 104.609 bytes)
Yeah that’s not particularly surprising. I like Accessors because it lets people ‘share’ these sorts of implementations, and takes some of the guess work out of it.
that is, I wouldnt be surprised if there was a more efficient/safe way to do this, and I’d hope that if I used Accessors, someone might contribute that implementation.
It’s also just cleaner syntax-wise
Also, the Accessors solution works for multi-byte characters, unlike the code from the first post:
julia> old = "абвгд"
julia> pos = 5
julia> old[pos]
'в': Unicode U+0432 (category Ll: Letter, lowercase)
julia> old[1:pos-1]*'C'*old[pos+1:end]
ERROR: StringIndexError: invalid index [4], valid nearby indices [3]=>'б', [5]=>'в'
Stacktrace:
[1] string_index_err(s::String, i::Int64)
@ Base ./strings/string.jl:12
[2] getindex(s::String, r::UnitRange{Int64})
@ Base ./strings/string.jl:470
[3] top-level scope
@ REPL[21]:1
julia> @set old[pos] = 'C'
"абCгд"
That's the implementation: https://github.com/JuliaObjects/Accessors.jl/blob/270e78fed32763096c448541148d520aa275e667/src/setindex.jl#L47.
May be upstreamed to Base if someone is up to making a PR, I guess...
There probably isn't a better way than the f function, if it used views.
Or you can use StringViews.jl which are mutable
Leandro Martínez has marked this topic as resolved.
Thanks all for the alternatives and tips. My use case is simple enough so that I will just keep the simple function for now.
Last updated: Dec 28 2024 at 04:38 UTC