Using strip.()

A particular case of strip. is not working.

julia> a = "  abc , (de f)  , gh "
"  abc , (de f)  , gh "

julia> b = split(a, ',')
3-element Array{SubString{String},1}:
 "  abc "   
 " (de f)  "
 " gh "     

julia> strip.(b, [' ', '(', ')'])    # the strip affect only the first element of b
3-element Array{SubString{String},1}:
 "abc"      
 " (de f)  "
 " gh "     

julia> strip.(b, [' '])       # with only one seperator it'll affect all elements
3-element Array{SubString{String},1}:
 "abc"   
 "(de f)"
 "gh"    

julia> strip.(b[2], [' ', '(', ')'])     # I don't get what happened here, i pressed Enter by mistake
3-element Array{SubString{String},1}:
 "(de f)"   
 " (de f)  "
 " (de f)  "

julia> strip(b[2], [' ', '(', ')'])     # strip works with multiple separators
"de f"

That my be me but I tried at first with " and got an error:

julia> strip.(split(a, [',']), [' ', '"'])
ERROR: DimensionMismatch("arrays could not be broadcast to a common size")
Stacktrace:
 [1] _bcs1 at ./broadcast.jl:438 [inlined]
 [2] _bcs at ./broadcast.jl:432 [inlined]
 [3] broadcast_shape at ./broadcast.jl:426 [inlined]
 [4] combine_axes at ./broadcast.jl:421 [inlined]
 [5] instantiate at ./broadcast.jl:255 [inlined]
 [6] materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,typeof(strip),Tuple{Array{SubString{String},1},Array{Char,1}}}) at ./broadcast.jl:753
 [7] top-level scope at none:0

julia> strip.(split(a, [',']), [' ', '\"'])
ERROR: DimensionMismatch("arrays could not be broadcast to a common size")
Stacktrace:
 [1] _bcs1 at ./broadcast.jl:438 [inlined]
 [2] _bcs at ./broadcast.jl:432 [inlined]
 [3] broadcast_shape at ./broadcast.jl:426 [inlined]
 [4] combine_axes at ./broadcast.jl:421 [inlined]
 [5] instantiate at ./broadcast.jl:255 [inlined]
 [6] materialize(::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1},Nothing,typeof(strip),Tuple{Array{SubString{String},1},Array{Char,1}}}) at ./broadcast.jl:753
 [7] top-level scope at none:0

@kristoffer.carlsson redirect me here, thanks, with this solution.

julia> strip.(b, ([' ', '(', ')'],))
3-element Array{SubString{String},1}:
 "abc"
 "de f"
 "gh"

Still I’m not comfortable with this definition of strip.. What can justify that the optional chars argument should be a Tuple of Array (Tuple of Tuple or Array of Array works too) for strip.?
Maybe I haven’t yet understood the dot effect on functions because in my mind strip.(b, [' ', '(', ')']) should give the same result as strip.(b, ([' ', '(', ')'],))

This is not specific to strip but to the dot syntax, i.e. strip.(...). For example

strip.(b, [' ', '(', ')'])

is equivalent of

[strip(b[1], ' '), strip(b[2], '('), strip(b[3], ')')]

In other words, the broadcast goes over both b and the vector of what to strip on at the same time. If you instead wanted

[strip(b[1],  [' ', '(', ')']), strip(b[2],  [' ', '(', ')']), strip(b[3],  [' ', '(', ')'])]

you can do this by making the other vector “look like a scalar” by wrapping it in either Ref or another tuple.

3 Likes

Or better still, write a comprehension for clarity:

[strip(w, ([' ', '(', ')'],)) for w in b]

Broadcasting is not the only tool in the toolbox.

4 Likes

I’ve always been a bit uncomfortable with the tuple wrapping, and especially Ref, because it’s a little bit unintuitive to read. You would then either write

strip.(b, ([' ', '(', ')'],))
# or
strip.(b, Ref([' ', '(', ')']))
# or perhaps better
strip.(b, ((' ', '(', ')'),))
# or
strip.(b, Ref((' ', '(', ')')))

In contrast, there’s a very nice version in StaticArrays, called Scalar, which has both a nicer name and requires fewer parens:

strip.(b, Scalar(' ', '(', ')'))

I think this makes it really clear what the intention is, and why you do it. Unfortunately, it relies on an otherwise unrelated package.

2 Likes

@kristoffer.carlsson The equivalence you gave was totally unexpected for me. I get it now, thank you! Yet it feels not really natural to me. Is there something I can read for more details about broadcast in Julia?

@StefanKarpinski I should do that more often, thanks for the reminder.

I understand now the ERROR: DimensionMismatch("arrays could not be broadcast to a common size"), I was sure it was the " char that didn’t work… Thank you all for your answers

See e.g. https://julialang.org/blog/2017/01/moredots, https://docs.julialang.org/en/v1/manual/arrays/index.html#Broadcasting-1.

3 Likes