# Beginner - How to Convert Values in a struct

Good afternoon,

I’m starting to play with Elixir and currently working my way through the Pragmatic Studio course while doing little experimentation on the side. I’m finding a whole lot to be confusing but I’m sure if I persist something will eventually click.

Anyway, like help or a pointer on structuring a module and functions. I’ve got the following module with a struct which I would like to convert between imperial and metric. How would I iterate though the measures to perform the conversion calculations, should each be measure have it’s own function for conversion which are piped together?

``````  defstruct(
measure: :metric,
location: :uk,
measures: %{
length: nil,
height: nil,
depth: nil,
weight: nil,
},
)

def convert_to_imperial( %Details{ measure: :metric } = details ) do
# Loop through measures -
# perform cm_to_inch for sizes
# kg_to_lbs for weight
# measure: to :imperial
end
def convert_to_imperial( %Details{} ), do: IO.puts("Not metric")

defp cm_to_inch(cm), do: Dec.mult(Dec.new(cm), Dec.new(0.3937)) |> Dec.to_float()
defp kg_to_lbs(kg),  do: Dec.mult(Dec.new(kg), Dec.new(2.2046)) |> Dec.to_float()
``````

``````iex:  a = Item.Detail%{ measure: metric, measures: %{ length: 44, height: 44, depth: 10, weight: 55 } }
iex:  Item.Detail.convert_to_imperial(a)``````

You can iterate on a map’s key/value pairs using `for`, for example:

``````  def convert_to_imperial(%Details{measure: :metric} = details) do
measures =
for {dimension, value} <- details.measures, into: %{} do
{dimension, metric_to_imperial(dimension, value)}
end
%Details{details | measures: measures}
end

defp metric_to_imperial(dimension, cm) when dimension in [:length, :height, :depth] do
Dec.mult(Dec.new(cm), Dec.new(0.3937)) |> Dec.to_float()
end

defp metric_to_imperial(:weight, kg) do
Dec.mult(Dec.new(kg), Dec.new(2.2046)) |> Dec.to_float()
end
``````

Although here since there aren’t many fields you can just build the map directly too:

``````  def convert_to_imperial(%Details{measure: :metric} = details) do
metric = details.measures
imperial = %{
length: cm_to_inch(metric.length),
height: cm_to_inch(metric.height),
# etc.
}
%Details{details | measures: imperial}
end
``````
1 Like