Sum the prices of all products over 20 using a stream pipeline.
← Streams and Pipelines · Ref: Q1142
Filter, map to price, then join with an addition function:
total <- cat products | filter by isExpensive | map with getPrice | join with addFloats | collect as Float
The join operation reduces a stream to a single value via a binary function. Each pipeline stage uses a named pure function. See Q1139 for join basics. See Q235 for stream operations reference.
Example
#!ek9 defines module qa.streams.sumaggregation defines class Product name as String? price as Float? default private Product() as pure Product() as pure -> name as String price as Float this.name :=? name this.price :=? price name() as pure <- rtn as String: String(name) price() as pure <- rtn as Float: Float(price) operator $ as pure <- rtn as String: `${name} \$${price}` override operator ? as pure <- rtn as Boolean: name? and price? defines function isExpensive() as pure -> product as Product <- rtn as Boolean? expensiveThreshold <- 20.0 rtn: product.price() > expensiveThreshold getPrice() as pure -> product as Product <- rtn as Float: product.price() addFloats() as pure -> a as Float b as Float <- rtn as Float: a + b defines program StreamSumDemo() stdout <- Stdout() products <- [ Product("Widget", 15.0), Product("Gadget", 45.0), Product("Gizmo", 30.0), Product("Trinket", 5.0), Product("Device", 60.0) ] // Filter to expensive products, extract price, sum total <- cat products | filter by isExpensive | map with getPrice | join with addFloats | collect as Float stdout.println(`Total of expensive items: ${total}`) // Count expensive items by collecting as list and measuring length expensiveList <- cat products | filter by isExpensive | collect as List of Product stdout.println(`Number of expensive items: ${length expensiveList}`)
Common mistakes
E50060 — EK9 uses cat/pipe stream syntax, not Java-style .stream() calls. Reduction uses 'join with' and a binary function. See ek9 -h E50060 for details.
Incorrect:
total <- products.stream()
Correct:
total <- cat products | filter by isExpensive | map with getPrice | join with addFloats | collect as Float
E07520 — A function used with 'filter by' must return Boolean; making isExpensive return Float triggers E07520 (must return a Boolean). See ek9 -h E07520 for details.
Incorrect:
<- rtn as Float? rtn: product.price()
Correct:
<- rtn as Boolean? expensiveThreshold <- 20.0 rtn: product.price() > expensiveThreshold
Other ways to ask this
- Write code to filter expensive products and sum their prices in a stream
- I have a list of products and need the total price of those costing more than 20
- Given a product list, compute the sum of prices above a threshold using a pipeline
- In Java I'd use stream().filter().mapToDouble().sum(). Write the EK9 equivalent
Coming from another language?
Java: stream().filter(p -> p.price > 20).mapToDouble(Product::getPrice).sum(). Python: sum(p.price for p in products if p.price > 20). Rust: iter().filter().map().sum(). EK9: cat | filter by | map with | join with | collect as.
Keywords: aggregate, filter, join, map, pipeline, price, reduce, stream, sum, total