Sort a list of Meeting records by date then by time using a stream pipeline.

← Streams and Pipelines · Ref: Q1199

Define a record with Date and Time fields, then use 'default operator' to get field-by-field comparison. Stream sort uses the <=> operator automatically.

RECORD DEFINITION

  Meeting with meetingDate, meetingTime, title fields
  'default operator' generates <=> comparing fields in declaration order (date first, then time, then title)

STREAM SORT

  sorted <- cat meetings | sort | collect as List of Meeting

The sort stage uses <=> from the default operator. Fields declared first have highest sort priority. Date before Time before title means chronological ordering happens naturally.

See Q1135 for record sort pipeline. See Q1195 for mixed-type record. See Q1197 for date sorting.

Example

defines module qa.streams.sortmeetingsbydatetime

  defines record

    Meeting
      meetingDate as Date: Date()
      meetingTime as Time: Time()
      title as String: String()

      Meeting() as pure
        ->
          theDate as Date
          theTime as Time
          theTitle as String
        this.meetingDate :=: theDate
        this.meetingTime :=: theTime
        this.title :=: theTitle

      default operator

  defines program

    SortMeetingsByDateTimeDemo()
      stdout <- Stdout()

      // === CREATE MEETINGS ===

      meetings <- List() of Meeting
      meetings += Meeting(2024-03-15, 14:00, "Retrospective")
      meetings += Meeting(2024-03-15, 09:00, "Sprint Planning")
      meetings += Meeting(2024-03-14, 16:00, "Code Review")
      meetings += Meeting(2024-03-16, 10:30, "Demo Day")

      // === SORT BY DATE THEN TIME (field declaration order) ===

      sorted <- cat meetings | sort | collect as List of Meeting
      stdout.println("Sorted meetings:")
      cat sorted > stdout

      // === FIRST TWO MEETINGS ===

      firstTwo <- cat meetings | sort | head 2 | collect as List of Meeting
      stdout.println("First two meetings:")
      cat firstTwo > stdout

      // === VERIFY ORDERING ===

      earliest <- Meeting(2024-03-14, 16:00, "Code Review")
      latest <- Meeting(2024-03-16, 10:30, "Demo Day")
      require earliest < latest

Common mistakes

E50001 — EK9 uses stream pipelines for sorting, not method calls. Define <=> via default operator and use cat | sort | collect. See ek9 -h E50060 for details.

Incorrect:

meetings.sort(Comparator.comparing(Meeting::getDate))

Correct:

sorted <- cat meetings | sort | collect as List of Meeting
Other ways to ask this
  • Build a record with Date and Time fields and sort instances in a stream.
  • I need to order meetings chronologically using cat, sort, and collect.
  • In Java I'd use Comparator.comparing(Meeting::getDate).thenComparing(Meeting::getTime). What is the EK9 equivalent?
  • Given meetings on different dates and times, sort them into chronological order.

Coming from another language?

Java: stream().sorted(Comparator.comparing(m -> m.date).thenComparing(m -> m.time)). Python: sorted(meetings, key=lambda m: (m.date, m.time)). Rust: sort_by_key with tuple. Go: sort.Slice with custom less function. EK9: declare fields in sort priority order + default operator + cat | sort | collect.

Keywords: collect, meeting, default operator, sort, time, chronological, stream, pipeline, date, record