How do I get the first or last item from a list in EK9?

← Common Collection Tasks · Ref: Q183

EK9 provides getOrDefault(0, default) for the first element and getOrDefault(length-1, default) for the last. Stream head and tail provide alternative approaches.

FIRST ELEMENT

Safe access with getOrDefault:

  first <- myList.getOrDefault(0, defaultVal)

Returns the first element or the default if the list is empty.

LAST ELEMENT

Access the last element by index:

  last <- myList.getOrDefault(length myList - 1, defaultVal)

STREAM HEAD FOR FIRST

Use head 1 in a stream pipeline:

  firstItems <- cat myList | head 1 | collect as List of Integer

Returns a list with 0 or 1 elements.

STREAM TAIL FOR LAST

Use tail 1 in a stream pipeline:

  lastItems <- cat myList | tail 1 | collect as List of Integer

See Q45 for List basics. See Q162 for safe list access. See Q125 for head/tail/skip in streams.

Example

defines module qa.collectiontasks.listfirstlast

  defines program
    ListFirstLastDemo()
      stdout <- Stdout()

      numbers <- [10, 20, 30, 40, 50]

      // === FIRST ELEMENT ===

      first <- numbers.getOrDefault(0, -1)
      stdout.println(`First: ${first}`)

      // === LAST ELEMENT ===

      lastIndex <- length numbers - 1
      last <- numbers.getOrDefault(lastIndex, -1)
      stdout.println(`Last: ${last}`)

      // === STREAM HEAD FOR FIRST ===

      firstViaStream <- cat numbers | head 1 | collect as List of Integer
      stdout.println(`Head 1: ${firstViaStream}`)

      // === STREAM TAIL FOR LAST ===

      lastViaStream <- cat numbers | tail 1 | collect as List of Integer
      stdout.println(`Tail 1: ${lastViaStream}`)

      // === EMPTY LIST SAFETY ===

      emptyList <- List() of Integer
      emptyFirst <- emptyList.getOrDefault(0, -1)
      stdout.println(`Empty first (default -1): ${emptyFirst}`)

      emptyHead <- cat emptyList | head 1 | collect as List of Integer
      stdout.println(`Empty head: ${emptyHead}`)

      // === SECOND ELEMENT ===

      second <- numbers.getOrDefault(1, -1)
      stdout.println(`Second: ${second}`)

Common mistakes

E50060 — EK9 List has no get() method. Use getOrDefault(index, default) for safe indexed access that always returns a value. See ek9 -h E50060 for details.

Incorrect:

first <- numbers.get(0)

Correct:

first <- numbers.getOrDefault(0, -1)

E50060 — EK9 List has no first() method. Use getOrDefault(0, default) or stream head 1 to safely access the first element. See ek9 -h E50060 for details.

Incorrect:

firstViaStream <- numbers.first()

Correct:

firstViaStream <- cat numbers | head 1 | collect as List of Integer
Other ways to ask this
  • How do I peek at the first element of a list in EK9?
  • How do I access the front or back of a list in EK9?
  • What is the EK9 equivalent of list.first() or list.last()?

Coming from another language?

Java: list.get(0) throws if empty, list.getFirst()/getLast() in Java 21+. Python: list[0], list[-1] throw IndexError if empty. Rust: vec.first(), vec.last() return Option. Go: slice[0] panics if empty. JavaScript: arr[0], arr.at(-1). Kotlin: list.first(), list.last() throw, list.firstOrNull(). EK9: getOrDefault(0, default) always safe, stream head/tail for pipeline approach.

Keywords: list, element, first, front, tail, getOrDefault, head, back, last, task, peek, collection