Find the cheapest product in a list.
← Operators and Expressions · Ref: Q1086
Sort by the price, then take the first:
cheapest <- cat products | sort by byPrice | head 1 | collect as List of Product
where byPrice is a pure comparator function:
byPrice() as pure -> left as Product right as Product <- rtn as Integer: left.price <=> right.price
For the maximum, sort by a descending comparator (right.price <=> left.price) and take head 1. A plain 'sort' uses the record's own <=> from 'default operator', which compares the fields in declaration order (name first) - it only finds the cheapest if price is the first field, so name the key with 'sort by'.
See Q1085 for sorting records. See Q1073 for descending sort.
Example
#!ek9 defines module qa.operators.findcheapestproduct defines record Product name as String: String() price as Float: Float() Product() -> name as String price as Float this.name :=: name this.price :=: price default operator defines function byPrice() as pure -> left as Product right as Product <- rtn as Integer: left.price <=> right.price byPriceDescending() as pure -> left as Product right as Product <- rtn as Integer: right.price <=> left.price defines program FindCheapestProductDemo() stdout <- Stdout() products <- List() of Product products += Product("Keyboard", 49.99) products += Product("Mouse", 19.99) products += Product("Monitor", 299.99) products += Product("Cable", 9.99) //Find cheapest: sort by price ascending, take first cheapest <- cat products | sort by byPrice | head 1 | collect as List of Product stdout.println(`Cheapest: ${cheapest}`) //Find most expensive: sort by price descending, take first priciest <- cat products | sort by byPriceDescending | head 1 | collect as List of Product stdout.println(`Priciest: ${priciest}`) //A plain 'sort' uses the record's own <=> from 'default operator', //which compares the fields in declaration order - name first firstByName <- cat products | sort | head 1 | collect as List of Product stdout.println(`First by name: ${firstByName}`)
Common mistakes
E50060 — EK9 has no .min() method. Use a stream pipeline: sort by a price comparator, then head 1 to get the cheapest.
Incorrect:
cheapest <- products.min()
Correct:
cheapest <- cat products | sort by byPrice | head 1 | collect as List of Product
Other ways to ask this
- Get the minimum item from a collection using a stream
- Extract the smallest record from a sorted list
- In Python I'd use min(). How do I find the minimum in EK9?
- I have a list of products and need the one with the lowest price
Coming from another language?
Java: Collections.min(list, Comparator.comparing(Product::price)). Python: min(products, key=lambda p: p.price). Rust: iter().min_by_key(). EK9: cat list | sort by byPrice | head 1 | collect.
Keywords: cheapest, find, head, minimum, smallest, sort, stream