# Handling of single object vs. 1-element array of object

**URL:** <https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949>\
**Category:** General Usage\
**Tags:** array\
**Created:** [August 6, 2021, 4:07pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949 "2021-08-06T16:07:11Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [August 6, 2021, 4:07pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/1 "2021-08-06T16:07:11Z")

</div>

See for example

```julia
mutable struct Coords
    x::Float64
    y::Float64
    z::Float64
end
Coords() = Coords(rand(), rand(), rand())
c5 = [Coords() for i in 1:5]
c1a = [Coords() for i in 1:1]
c1b = Coords()

fieldnames(typeof(c1b)) # (:x, :y, :z)
fieldnames(c1a) # ()
fieldnames(typeof(c1a[1])) # (:x, :y, :z)

length(c5) # 5
length(c1a) # 1
length(c1b) # throwing error

```

Before I clobber some code using many if typeof(x)==y, is there a more elegant way to handle or distinguish single objects vs. arrays of objects?

---

<div class="post-metadata">

**Author:** ![Paulo\_Jabardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulo_jabardo/32/3196_2.png) [@Paulo\_Jabardo](https://discourse.julialang.org/u/Paulo_Jabardo)\
**Post date:** [August 6, 2021, 4:12pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/2 "2021-08-06T16:12:49Z")

</div>

I am not sure I understand what you want but I think in this case multiple dispatch is your friend:

```julia
# First method
function myfun(x::Coords)
# Do something with a single element
end

# Second method
function myfun(x::Vector{Coords})
# Do something with an array
end

```

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [August 6, 2021, 4:25pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/3 "2021-08-06T16:25:26Z")

</div>

OK for the example.

I am dealing with an unknown number of types (which could be higher dimensional as well).  
So I would prefer to have a test like is\_single/is\_vector/is\_matrix.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [August 6, 2021, 4:29pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/4 "2021-08-06T16:29:57Z")

</div>

You can dispatch on the dimension as well

```julia
myfun(x::Cords) = ...
myfun(x::Vector{Coords})
myfun(x::Matrix{Coods})

```

etc.

Maybe the best bet is to choose a type you think is most natural, `Vector`, `Matrix` etc. and then for the other methods, just convert it to that type.

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [August 6, 2021, 4:53pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/5 "2021-08-06T16:53:28Z")

</div>

Right, but still complicating my code…  
I finally came up with this:

```julia
julia> is_single(x) = !hasmethod(length, tuple(typeof(x)))
is_single (generic function with 1 method)

julia> is_single(c1a)
false

julia> is_single(c1b)
true

```

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [August 6, 2021, 5:01pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/6 "2021-08-06T17:01:40Z")

</div>

If that works for you, then that’s fine.

One final thing to note is that you can dispatch on `AbstractArray`, which will catch all arrays of any dimension.

```julia
myfun(x::AbstractArray{Coords}) = ...
myfun(x::Coords) = myfun([x])

```

---

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [August 6, 2021, 5:03pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/7 "2021-08-06T17:03:38Z")

</div>

Note that ` is_single(1) == is_single([1]) == false`, and that this is quite slow. Dispatch on `f(x::AbstractArray)` vs. `f(x)` will I think do what you want. Or `x isa AbstractArray` if you want a test within a function:

```julia
julia> @btime is_single(1)
  323.328 ns (3 allocations: 144 bytes)
false

julia> @btime 1 isa AbstractArray
  0.001 ns (0 allocations: 0 bytes)
false

```

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [August 6, 2021, 5:15pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/8 "2021-08-06T17:15:13Z")

</div>

Cool, so

```julia
julia> issingle(x) = !(typeof(x) <: AbstractArray)
issingle (generic function with 1 method)

julia> issingle(c1a)
false

julia> issingle(c1b)
true

```

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [August 6, 2021, 6:30pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/9 "2021-08-06T18:30:48Z")

</div>

I rarely come across situations where I don’t know if I’m dealing with a scalar or an array _without_ running the code. This is also why explicit syntactic broadcasting is preferred over dispatching to different methods for scalar vs array (except when you need non-broadcasting behavior, e.g. matrix multiplication).

I suspect a code smell here. Where do these arrays come from, and why can’t you tell if objects are scalar or arrays without running the code?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [August 6, 2021, 6:52pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/10 "2021-08-06T18:52:45Z")

</div>

I’m going to second this. This situation usually comes up from new Julia users coming from Matlab, and the real solution usually is to use broadcasting and not quite vector/matrix versions of your functions.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [August 6, 2021, 8:29pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/11 "2021-08-06T20:29:03Z")

</div>

To elaborate on this, Matlab (and Python and R) want you to push vectorized operations “in” as far as possible so that you can pass large arrays into the primitive operations that are written in fast C code, allowing them to amortize over the entire array and try to make up for the slowness of the outer language. Julia wants you to do the opposite: push vectorization “out” as far as possible and leave it to the very last moment. Express your core operations in terms of scalars and then only do broadcasting when you need to. This works fine because the outer language is fast in itself and doesn’t need you to force everything into vectorized operations. In fact, this approach is typically more efficient since it uses less memory and has better memory locality by combining multiple operations on the same data instead of having to make many passes over the same data computing a stage at a time as Matlab, Python and R would.

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [August 6, 2021, 9:19pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/12 "2021-08-06T21:19:23Z")

</div>

Three times agree with the last posters.

Coming from Matlab and translating a Matlab serializer code.  
To be specific, a Julia serializer translating into Matlab compatible structures, so departing from a MAT.jl approach using HDF as intermediate format.

So of course I know what is single or Vector, just a bit hesitant to accept multiple dispatch as the [panacea](https://en.wikipedia.org/wiki/Law_of_the_instrument). If not sufficiently generalizable to few types, I imagine a lot of code replication. There might be a threshold by the number of ifs to convert to MD though.

Thanks for giving a hand, maybe these little bits and pieces on discourse make it some day into the manual.

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [August 6, 2021, 9:29pm UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/13 "2021-08-06T21:29:35Z")

</div>

If you run into any specific bits that feel weird in Julia, feel free to post an example. Usually, the answer is just to use broadcasting, but the specifics are sometimes a little more complicated/require rethinking the approach a little.

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [August 7, 2021, 6:22am UTC](https://discourse.julialang.org/t/handling-of-single-object-vs-1-element-array-of-object/65949/14 "2021-08-07T06:22:36Z")

</div>

Here we go: [https://discourse.julialang.org/t/how-to-dispatch-this-serializer-function/65981](https://discourse.julialang.org/t/how-to-dispatch-this-serializer-function/65981)
