17

Let's say I have an Array variable called p:

julia> p = [5]
julia> typeof(p)
Array{Int64,1}

How should I convert it to scalar? p may also be 2-dimensional:

julia> p = [1]'' 
julia> typeof(p)
Array{Int64,2}

(Note: the double transpose trick to increase dimentionality might not work in future versions of Julia)

Through appropriate manipulation, I can make p of any dimension, but how should I reduce it to a scalar?


One viable approach is p=p[1], but that will not throw any error if p has more than one element in p; so, that's no good to me. I could build my own function (with checking),

function scalar(x)
    assert(length(x) == 1)
    x[1]
end

but it seems like it must be reinventing the wheel.

What does not work is squeeze, which simply peels off dimensions until p is a zero-dimensional array.

(Related to Julia: convert 1x1 array from inner product to number but, in this case, operation-agnostic.)

Community
  • 1
  • 1
Frames Catherine White
  • 27,368
  • 21
  • 87
  • 137

2 Answers2

10

If you want to get the scalar but throw an error if the array is the wrong shape, you could reshape:

julia> p1 = [4]; p2 = [5]''; p0 = []; p3 = [6,7];

julia> reshape(p1, 1)[1]
4

julia> reshape(p2, 1)[1]
5

julia> reshape(p0, 1)[1]
ERROR: DimensionMismatch("new dimensions (1,) must be consistent with array size 0")
 in reshape at array.jl:122
 in reshape at abstractarray.jl:183

julia> reshape(p3, 1)[1]
ERROR: DimensionMismatch("new dimensions (1,) must be consistent with array size 2")
 in reshape at array.jl:122
 in reshape at abstractarray.jl:183
DSM
  • 342,061
  • 65
  • 592
  • 494
5

You should use only, which was introduced in Julia v1.4

julia> only([])
ERROR: ArgumentError: Collection is empty, must contain exactly 1 element
Stacktrace:
  [1] only(x::Vector{Any})
    @ Base.Iterators ./iterators.jl:1323
  [...]

julia> only([1])
1

julia> only([1 for i in 1:1, j in 1:1, k in 1:1]) # multidimensional ok
1
Frames Catherine White
  • 27,368
  • 21
  • 87
  • 137
BallpointBen
  • 9,406
  • 1
  • 32
  • 62