Write an EK9 class with comparison operators so I can sort a list of them.
← Functions and Methods · Ref: Q1065
Define the <=> (spaceship) operator: it is the type's sameness, and the compiler generates ==, <>, <, <=, > and >= from it. Writing any of those for the type itself is an error (E07181). Add a hand-written #? that hashes what <=> compares (E07184 otherwise), $ for string display, and ? because a class with properties needs it (E07235 otherwise).
defines class
Product
productName as String: String()
price as Float: 0.0
Product()
->
productName as String
price as Float
this.productName :=: productName
this.price :=: price
override operator ? as pure <- rtn as Boolean: productName? and price?
operator <=> as pure -> other as Product <- rtn as Integer: price <=> other.price
operator #? as pure <- rtn as Integer: #? price
operator $ as pure <- rtn as String: `${productName}: ${price}`
Now you can sort, and use every comparison:
cat products | sort > stdout cheapest <- first <? second
For a different ordering (by name, say) write a comparator function and use 'sort by', never a second <=>.
See Q1049 for comparison on records. See Q1047 for hashcode. See Q1055 for default operator.
Example
defines module qa.functions.writesortableclass defines class Product productName as String: String() price as Float: 0.0 default private Product() Product() -> productName as String price as Float this.productName :=: productName this.price :=: price operator <=> as pure -> other as Product <- rtn as Integer: price <=> other.price //== <> < <= > >= are all generated from <=>; #? hashes what <=> compares operator #? as pure <- rtn as Integer: #? price override operator ? as pure <- rtn as Boolean: productName? and price? operator $ as pure <- rtn as String: `${productName}: ${price}` defines program SortableClassDemo() stdout <- Stdout() products <- [ Product("Widget", 9.99), Product("Gadget", 24.99), Product("Doohickey", 4.99) ] //Sort by price (uses <=> operator) stdout.println("Sorted by price:") cat products | sort > stdout //Get cheapest cheapest <- Product("Widget", 9.99) <? Product("Gadget", 24.99) stdout.println(`Cheapest: ${cheapest}`)
Common mistakes
E07181 — The <=> operator is the type's sameness and the compiler generates ==, <>, <, <=, > and >= from it. Writing == for the type itself is error E07181. See ek9 -h E07181 for details.
Incorrect:
operator <=> as pure -> other as Product <- rtn as Integer: price <=> other.price operator == as pure -> other as Product <- rtn as Boolean: price == other.price
Correct:
operator <=> as pure -> other as Product <- rtn as Integer: price <=> other.price
Other ways to ask this
- How do I make a class sortable in EK9?
- Write a class I can use in a sorted stream pipeline
- Code a class with all comparison operators
Coming from another language?
Java: implements Comparable<T>. Python: __lt__, __gt__. Rust: derive Ord. EK9: define <=> once; the compiler generates ==, <>, <, <=, >, >= from it.
Keywords: coder, code, write, operator, comparison, class, sort