# Function that accepts scalars or one element vectors/ arrays

**URL:** https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040
**Category:** New to Julia
**Tags:** function, numeric-primitives
**Created:** [July 11, 2022, 8:40am UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040 "2022-07-11T08:40:51Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)
#### Post date: [July 11, 2022, 8:40am UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/1 "2022-07-11T08:40:51Z")

</div>

I would like to restrict a function to accept only argument values which contain only one number, how can this be achieved? My example below accept already scalars, vectors and arrays, but the argument value is not restricted to only one number, any ideas?

```julia
function _takeOneNumberInputsOnly(_oneNumber::Union{Vector{<:Number}, Array{<:Number}, Number})
    println("typeof(): ", typeof(_oneNumber), ", \t size(): ", size(_oneNumber))
end

# Example Inputs
oneElementVector = [1.2]
twoElementVector = [1, 2]
oneElementArray = ones(1,1)
scalar_value = 2.3

# This should be fine:
_takeOneNumberInputsOnly(oneElementVector)
_takeOneNumberInputsOnly(scalar_value)
_takeOneNumberInputsOnly(oneElementArray)

# This should throw an error:
_takeOneNumberInputsOnly(twoElementVector)

```

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [July 11, 2022, 9:42am UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/2 "2022-07-11T09:42:51Z")

</div>

You cannot directly dispatch on the size of a (non static) array, thus probably the best is use an `@assert`.

Alternatively you could add an inner function witch dispatches on the `Val` of the length, but that’s probably too cumbersome.

Ps: Vector is an alias of Array, so the Union there is redundant. Also `AbstractArray` is probably better (accept views, etc)

---

<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: [July 11, 2022, 10:52am UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/3 "2022-07-11T10:52:15Z")

</div>

Use the `only` function on your input arg.

---

<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: [July 11, 2022, 11:02am UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/4 "2022-07-11T11:02:01Z")

</div>

```julia
function _takeOneNumberInputsOnly(_oneNumber)
    num = only(_oneNumber)
    println("typeof(): ", typeof(num), ", \t size(): ", size(num))
end

```

Works for all cases (I _think_.)

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [July 11, 2022, 1:44pm UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/5 "2022-07-11T13:44:44Z")

</div>

> [@lmiq](#):
>
> probably the best is use an `@assert`

[`@assert` statements could be disabled at various optimization levels](https://docs.julialang.org/en/v1/base/base/#Base.@assert), so it’s usually better to use `throw(ArgumentError("message"))`.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [July 11, 2022, 1:55pm UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/6 "2022-07-11T13:55:40Z")

</div>

Yeah… I think that help entry must be improved. First it says:

```julia
Preferred syntax for writing assertions.

```

which does not suggest it is a debugging tool that should not be used _at all_ in production code.

Then it mentions verifying passwords, which seems a pretty specific case, to end with `nor should side effects needed for the function to work correctly be used inside of asserts.`

which I really don’t understand what it means.

edit: added a pull request here trying to make it more clear: [clarify assert doc entry by lmiq · Pull Request #45998 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/45998)

---

<div class="post-metadata">

### Author: ![uje](https://avatars.discourse-cdn.com/v4/letter/u/5f9b8f/32.png) [@uje](https://discourse.julialang.org/u/uje)
#### Post date: [July 11, 2022, 2:17pm UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/7 "2022-07-11T14:17:14Z")

</div>

Julia makes it easy for you, just use multiple dispatch as its best and more readable. From your question, only scalars and vectors/arrays are needed, so:

```julia
function _takeOneNumberInputsOnly(_oneNumber::Number)
    only(_oneNumber)
    # do whatever you want here
end

```

```julia
function _takeOneNumberInputsOnly(_oneNumber::Array{<:Number})
    only(_oneNumber)
    # do whatever you want here
end

```

```julia
_takOneNumberInputsOnly([12, 23]) # raises the error below

```

> ArgumentError: Collection has multiple elements, must contain exactly 1 element
> 
> Stacktrace:  
> [1] only(x::Vector{Int64})  
> @ Base.Iterators ./iterators.jl:1358  
> [2] top-level scope  
> @ In[22]:1  
> [3] eval  
> @ ./boot.jl:373 [inlined]  
> [4] include\_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)  
> @ Base ./loading.jl:1196

the **only()** function takes care of everything for you, so you don’t have to worry checking if the user entered more than **one** numbers.

---

<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: [July 11, 2022, 2:19pm UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/8 "2022-07-11T14:19:12Z")

</div>

one answer to consider is to not do this. instead, only define it for number and some call it with vectors. you are likely coming from Matlab which doesn’t give you good tools, but in Julia, it’s often worth thinking whenever you see a 1 element vector/matrix since it’s usually a sign of bad code.

---

<div class="post-metadata">

### Author: ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)
#### Post date: [July 13, 2022, 10:30am UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/9 "2022-07-13T10:30:45Z")

</div>

> [@ellocco](#):
>
> `_oneNumber::Union{Vector{<:Number}, Array{<:Number}, Number}`

Thanks DNF! - This works for me!

---

<div class="post-metadata">

### Author: ![ellocco](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ellocco/32/31331_2.png) [@ellocco](https://discourse.julialang.org/u/ellocco)
#### Post date: [July 13, 2022, 12:23pm UTC](https://discourse.julialang.org/t/function-that-accepts-scalars-or-one-element-vectors-arrays/84040/10 "2022-07-13T12:23:19Z")

</div>

I have tried hard to write a minimalist sample code of the situation I am facing,  
but fail :-(.  
Part of my data is stored in a MAT-file (generated by Julia package MAT).  
After reading back the vector `eis_frequency_Shunt` which is nested inside this MAT,  
the result is of type `Vector(Any)`. In the next step I take out one element of the  
vector and the result is again a vector (`Vector{Any}`), holding one element.  
Now it happens that the function that takes this one-element vector fails to execute,  
because the compiler complains about a format mismatch (see below).  
I had to use the notation `[]` to make it possible to run my script,  
the annoying thing was, it took a while for me, to figure out the root-cause of the  
crash.  
Here a snippet of my code:

```julia
[...]
_frequ_Shunt = eis_frequency_Shunt[indx_in_FFT_results]
_A, _B = MyLibCalibrationAmplPhase(_frequ_Shunt, B, C, D, E)

```

And here the definition of the function:

```julia
function MyLibCalibrationAmplPhase(_frequency::Real, _data_pts::Vector{<:Number},
 _sampl_rate::Real, _num_periods::Int=10, _LSQ_method::Int=0)
[...]
end

```

And here the error message (the first two lines are debugging output):

```julia
DBG: _frequ_Shunt, type: Vector{Any}, size: (1,)
DBG: eis_frequency_Shunt, type: Vector{Any}, size: (46,)
[...]
ERROR: MethodError: no method matching MyLibCalibrationAmplPhase(::Vector{Any}, ::Vector{Float64}, ::Float64, ::Int64, ::Int64)
Closest candidates are:
  MyLibCalibrationAmplPhase(::Real, ::Vector{<:Number}, ::Real, ::Int64, ::Int64) at C:\data\git_repos\hycenta_julia\Julia_Modules\SignalAnalysis\HyCentaHarmonicSignalAnalysis.jl:148
  MyLibCalibrationAmplPhase(::Real, ::Vector{<:Number}, ::Real, ::Int64) at C:\data\git_repos\hycenta_julia\Julia_Modules\SignalAnalysis\HyCentaHarmonicSignalAnalysis.jl:148  
  MyLibCalibrationAmplPhase(::Real, ::Vector{<:Number}, ::Real) at C:\data\git_repos\hycenta_julia\Julia_Modules\SignalAnalysis\HyCentaHarmonicSignalAnalysis.jl:148

```

I can avoid this error by adding empty squared brackets: `[]`:

```julia
 _frequ_Shunt = eis_frequency_Shunt[indx_in_FFT_results][]

```

This was the trigger to think about, how to improve my function,  
to handle this strange situation.
