Why must I sort before grouping in an EK9 stream pipeline?

← Streams and Pipelines · Ref: Q891

EK9 stream group uses change-detection: it creates a new group when the hashcode changes between adjacent items. Without sorted input, items with the same key scattered throughout the stream produce multiple incomplete groups.

CORRECT PATTERN

  cat items | sort | group > collection

Sorting ensures identical items are adjacent, so group detects each run correctly.

INCORRECT PATTERN

  cat items | group > collection        // ERROR: E10040

Without sort, group may split identical items into separate groups.

TYPE-CHANGING INVALIDATES SORT

  cat items | sort | map with transform | group > collection  // ERROR: E10040

The map changes the stream type, making the preceding sort irrelevant. Add another sort after the map.

FILTER PRESERVES SORT

  cat items | sort | filter by predicate | group > collection  // OK

Filter removes items without changing type, so sort remains valid.

See Q235 for stream operations. See Q237 for streams vs loops.

Example

defines module qa.streams.sortbeforegroup

  defines program

    SortBeforeGroupDemo()
      stdout <- Stdout()

      grouped <- List() of List of String
      cat ["A", "B", "A", "C", "B"] | sort | group > grouped

      stdout.println(`Groups found: ${length grouped}`)

Common mistakes

E10040 — Group uses change-detection on adjacent items. Without sort, identical items scattered in the stream produce incomplete groups. Add sort before group. See ek9 -h E10040 for details.

Incorrect:

      cat ["A", "B", "A", "C", "B"] | group > grouped

Correct:

      cat ["A", "B", "A", "C", "B"] | sort | group > grouped
Other ways to ask this
  • What triggers E10040 SORT_REQUIRED_BEFORE_GROUP?
  • Why does group need a preceding sort in streams?
  • How does change-detection grouping work in EK9?

Coming from another language?

Java: Collectors.groupingBy uses HashMap, order irrelevant. Python: itertools.groupby requires sorted input but no compile-time check. Go: no built-in group. Rust: group_by requires sorted, no compile check. EK9: compiler enforces sort before group at compile time.

Keywords: detection, change, collect, sort, E10040, adjacent, stream, pipeline, order, group