# Enum.min_by/max_by returns the values of type Decimal vise versa

In “Product” a model I have “price” of type https://github.com/ericmj/decimal

This code finds min and max prices, but precisely in the opposite way:

``````      min = Enum.min_by(products, &(&1.price)).price
max = Enum.max_by(products, &(&1.price)).price
``````

“min” contains the biggest price, “max” the smallest one. Why?

`Enum.min_by/2` and `Enum.max_by/2` work using `Kernel.</2` and `Kernel.>/2` respectively. You can’t use those to compare `Decimal` (or about any other struct).

You need to `Enum.reduce/3` using `Decimal.max/2`/`Decimal.min/2`, eg:

``````def minimal_decimal(products) do
Enum.reduce(tl(products), hd(products).price, &Decimal.min(&1.price, &2))
end
``````
3 Likes

Why not to sort instead using Decimal.mix/max or Decimal.cmp?

Because `Enum.reduce/3` is `O(n)`, sorting is `O(n log n)` at least. Reading the last element from a list is `O(n)` again. So sorting and taking out the values is unnecessarily slow, compared to a single pass.

2 Likes

That’s true for large lists. If I had a list 10-50-100 elements, sorting would be simpler, right? A differnce in performance wouldn’t be noticiable

Perhaps…

But as I do not know your input, and also assume that especially lists can become arbitrarily large, I’d strictly prefer the reduce.

Usually, I’d even create a `min_max` version, which gives me minimal and maximal value of the list in a single pass.

1 Like