Inconsistency with `reduce(vcat, v)` when the vector has a single element

Hello! I guess that this might have been discussed somewhere. But I couldn’t find it. I’ll put an example to show the problem, which in my opinion needs at least some consideration

julia> vcat(1,2) == reduce(vcat, [1,2])
true

On the other hand,

julia> vcat(1) == reduce(vcat, [1])
false

which I find it problematic. The problem comes from reduce which behaves differently when a single element is passed as a second argument. Moreover the type is not the same neither if a single element is passed

julia> reduce(vcat, ["a"])
"a"

julia> reduce(vcat, ["a",["b","c"]])
3-element Vector{String}:
 "a"
 "b"
 "c"

I found myself using it together with an extra vcat to avoid this corner-case

julia> vcat(reduce(vcat, ["a"]))
1-element Vector{String}:
 "a"

julia> vcat(reduce(vcat, ["a",["b","c"]]))
3-element Vector{String}:
 "a"
 "b"
 "c"
1 Like

https://github.com/JuliaLang/julia/issues/34395

2 Likes

I haven’t compared the performance but I’ve been using
https://docs.julialang.org/en/v1/base/iterators/#Base.Iterators.flatten
to do what I think you are trying to achieve.

1 Like

See also a previous discussion and the linked issues:

https://github.com/JuliaLang/julia/issues/31169

https://github.com/JuliaLang/julia/issues/34380

2 Likes

The problem with flatten is that I obtain characters instead of substrings. Here the example,

julia> collect(Iterators.flatten(["ab", ["cd"]]))
3-element Vector{Any}:
 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
 "cd"

But can be an option if I wrap all the free elements in the array with ["ab"]

julia> collect(Iterators.flatten([["ab"], ["cd", "ef"]]))
3-element Vector{String}:
 "ab"
 "cd"
 "ef"

UPDATE: It seems to work and since the type-instability was indeed into the array itself, I think this can be a solution for this case. Thanks @lawless-m and thank you all for your help. Interesting to find these issues you mentioned.

1 Like