Write code to filter a list and collect the results into a new list.

← Streams and Pipelines · Ref: Q1035

Use a stream pipeline with filter and collect:

  longNames <- cat names
    | filter by isLongName
    | collect as List of String

The filter function must return Boolean. Items where the function returns true pass through.

  isLongName() as pure
    -> name as String
    <- rtn as Boolean?
    minLength <- 4
    rtn: name.length() > minLength

You can combine filter with other operations:

  cat names
    | filter by isLongName
    | sort
    | head 3
    | collect as List of String

This reads naturally: take names, keep long ones, sort them, take first 3, collect into a list.

For counting matches, use the collected list:

  matches <- cat items
    | filter by predicate
    | collect as List of T
  count <- matches.length()

Example

defines module qa.streams.coderfiltercollect

  defines function

    isLongName() as pure
      -> name as String
      <- rtn as Boolean?

      minLength <- 4
      rtn: name.length() > minLength

  defines program

    FilterCollectDemo()
      stdout <- Stdout()

      names <- ["Al", "Alice", "Bob", "Charlie", "Dave", "Elizabeth"]

      //Filter and collect
      longNames <- cat names
        | filter by isLongName
        | collect as List of String
      stdout.println(`Long names: ${longNames}`)

      //Filter, sort, and take first 2
      topTwo <- cat names
        | filter by isLongName
        | sort
        | head 2
        | collect as List of String
      stdout.println(`Top two: ${topTwo}`)

Common mistakes

E50060 — A List has no filter() method, so the call is not resolved (E50060). EK9 has no method-chained collection operations: use a stream pipeline, cat source | filter by fn | collect as Type. See ek9 -h E50060 for details.

Incorrect:

      longNames <- names.filter(isLongName)

Correct:

      longNames <- cat names
        | filter by isLongName
        | collect as List of String
Other ways to ask this
  • How do I filter items from a list into a new list in EK9?
  • Show the EK9 way to select matching items from a collection
  • Write a stream pipeline that filters and collects
  • Collect filtered stream results into a new List.
  • I need to capture a pipeline's output as a List instead of printing it
  • In Java I'd use .collect(Collectors.toList()). Write the EK9 equivalent
  • Given a filtered stream, materialise the results into a List of Integer
  • Store the output of a stream pipeline in a variable using collect as

Coming from another language?

Java: .collect(Collectors.toList()). Python: list(filter(...)). EK9 uses 'cat source | filter by fn | collect as Type' instead of loops with conditionals.

Keywords: stream, collect, materialise, capture, result, list, filter, pipeline, coder