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?
NobbZ
March 30, 2019, 5:00pm
2
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?
NobbZ
March 30, 2019, 5:09pm
4
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
NobbZ
March 30, 2019, 5:16pm
6
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