# Creating a struct with 1D length using unitful.jl

**URL:** <https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212>\
**Category:** New to Julia\
**Tags:** unitful\
**Created:** [September 24, 2020, 2:38pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212 "2020-09-24T14:38:42Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jdossgollin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdossgollin/32/18166_2.png) [@jdossgollin](https://discourse.julialang.org/u/jdossgollin)\
**Post date:** [September 24, 2020, 2:38pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/1 "2020-09-24T14:38:42Z")

</div>

I’m trying to build a data type to hold a measurements of a quantity. I know that this quantity will be a length, but don’t know a priori what unit that length will be. I’m having a bit of trouble coming up with syntax to guarantee that `heights` will be a length using the `Unitful` types.

```julia
using Unitful

struct Measurements
    heights::Array{Unitful.Quantity,1} # this line
end

```

Is there a better way to do this? Thanks for the help!

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [September 24, 2020, 2:43pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/2 "2020-09-24T14:43:06Z")

</div>

Perhaps like this?

```julia
julia> struct Measurements{T <: Quantity{<:Any, Unitful.𝐋}}
           heights::Vector{T}
       end

julia> Measurements([1u"m", 2u"cm"])
Measurements{Quantity{Rational{Int64},𝐋,Unitful.FreeUnits{(m,),𝐋,nothing}}}(Quantity{Rational{Int64},𝐋,Unitful.FreeUnits{(m,),𝐋,nothing}}[1//1 m, 1//50 m])

julia> Measurements([1u"m", 2u"s"])
ERROR: MethodError: no method matching Measurements(::Array{Quantity{Int64,D,U} where U where D,1})

```

Edit: If you don’t want the type parameter you can use

```julia
julia> struct Measurements
           heights::Vector{<: Quantity{<:Any, Unitful.𝐋}}
       end

```

---

<div class="post-metadata">

**Author:** ![jdossgollin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdossgollin/32/18166_2.png) [@jdossgollin](https://discourse.julialang.org/u/jdossgollin)\
**Post date:** [September 24, 2020, 3:02pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/3 "2020-09-24T15:02:52Z")

</div>

thanks, sorry for the obvious question

---

<div class="post-metadata">

**Author:** ![ggggggggg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ggggggggg/32/265_2.png) [@ggggggggg](https://discourse.julialang.org/u/ggggggggg)\
**Post date:** [September 24, 2020, 5:15pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/4 "2020-09-24T17:15:49Z")

</div>

You can also just specify a specific length unit, and on insertion convert from the given length to the length required by the vector. Is there a reason you want to keep track of what unit was originally provided?

---

<div class="post-metadata">

**Author:** ![jdossgollin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdossgollin/32/18166_2.png) [@jdossgollin](https://discourse.julialang.org/u/jdossgollin)\
**Post date:** [September 28, 2020, 3:14pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/5 "2020-09-28T15:14:17Z")

</div>

This may actually be a better approach – there is no need to track the original unit and it would be helpful to convert by default to a unit (say feet)

---

<div class="post-metadata">

**Author:** ![Daniel\_Berge](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_Berge](https://discourse.julialang.org/u/Daniel_Berge)\
**Post date:** [September 28, 2020, 5:11pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/6 "2020-09-28T17:11:08Z")

</div>

> [@fredrikekre](#):
>
> ```julia
> struct Measurements
> heights::Vector{<: Quantity{<:Any, Unitful.𝐋}}
> end
> 
> ```

I usually use the following when I’ve build functionality around `Unitful.jl`. There are many different aliases for common dimensions.

```julia
struct Measurements
    heights::Vector{<:Unitful.Length}
end

```

---

<div class="post-metadata">

**Author:** ![jdossgollin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jdossgollin/32/18166_2.png) [@jdossgollin](https://discourse.julialang.org/u/jdossgollin)\
**Post date:** [September 28, 2020, 5:55pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/7 "2020-09-28T17:55:25Z")

</div>

Cool, if one wanted to convert to feet by default is a constructor the place to do it? Something like

```julia
struct Measurements
    heights::Vector{<: Unitful.Length}
    function Measurements(x::Vector{<: Unitful.Length})
       x_conv = [Unitful.uconvert(Unitful.u"ft", xi) for xi in x]
       new(x_conv)
    end
end

```

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [September 28, 2020, 6:27pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/8 "2020-09-28T18:27:08Z")

</div>

You can use `upreferred` to transform to SI units

---

<div class="post-metadata">

**Author:** ![ggggggggg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ggggggggg/32/265_2.png) [@ggggggggg](https://discourse.julialang.org/u/ggggggggg)\
**Post date:** [September 28, 2020, 6:33pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/9 "2020-09-28T18:33:37Z")

</div>

I think this is the intended way, and it works better for performance since the vector is concretely typed:

```julia
julia> using Unitful

julia> a = Vector{typeof(1.0u"μm")}()
push!0-element Array{Quantity{Float64,𝐋,Unitful.FreeUnits{((μm,),𝐋,nothing}},1}

julia> push!(a,1u"m")
push1-element Array{Quantity{Float64,𝐋,Unitful.FreeUnits{(μm,),𝐋,nothing}},1}:
 1.0e6 μm

julia> push!(a,7u"cm")
2-element Array{Quantity{Float64,𝐋,Unitful.FreeUnits{(μm,),𝐋,nothing}},1}:
   1.0e6 μm
 70000.0 μm

```

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [September 28, 2020, 6:41pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/10 "2020-09-28T18:41:22Z")

</div>

To make your struct concrete, but also more flexible, I’d do something like this:

```julia
#+begin_src julia
using Unitful
struct Measurements{T <: Unitful.Length}
    heights::Vector{T}
    Measurements(x::Vector{<: Unitful.Length}) = [Unitful.uconvert(Unitful.u"ft", xi) for xi in x]
end

Measurements([1u"cm", 1.0u"mm", 1e10u"fm"])

#+end_src

#+RESULTS:
: 3-element Array{Quantity{Float64,𝐋,Unitful.FreeUnits{(ft,),𝐋,nothing}},1}:
: 0.03280839895013123 ft
: 0.0032808398950131233 ft
: 3.280839895013124e-5 ft

```

---

<div class="post-metadata">

**Author:** ![Daniel\_Berge](https://avatars.discourse-cdn.com/v4/letter/d/eb9ed0/32.png) [@Daniel\_Berge](https://discourse.julialang.org/u/Daniel_Berge)\
**Post date:** [September 28, 2020, 7:03pm UTC](https://discourse.julialang.org/t/creating-a-struct-with-1d-length-using-unitful-jl/47212/11 "2020-09-28T19:03:21Z")

</div>

If you want to change the preferred units for your use case, see [Conversion/promotion · Unitful.jl](https://painterqubits.github.io/Unitful.jl/stable/conversion/#Unitful.preferunits)

So for example, to use feet instead of meters, you could do

```julia
using Unitful
Unitful.preferredunits(u"ft")

upreferred(2u"m")
# 2500//381 ft

```
