CH05-L03 · applied

The filter() macro

Create a new list containing only items that satisfy a condition.

General CELRuns hereDocumented
What will I learn?

You understand that filter() returns a list and does not modify the original collection.

Where will I try it?

Directly below, in the browser playground.

What do I do?

Run both modes, compare where their values come from, then complete the task.

Try CEL · browser pilot

Try both ways to supply values

Define local values inside one CEL expression, or provide variables as JSON input. Everything runs in your browser.

CEL pilot subset
One self-contained CEL expressioncel.bind() gives a local name to a value and returns the result of the final expression.

cel.bind()cel.bind() is an optional official extension. It is not part of the core CEL language and may not be enabled by every host application.

Tip: press Ctrl/⌘ + Enter to run.
Result

Press Run CEL to evaluate the active example.

Pilot scope: literals, explicit conversions, local cel.bind() variables, JSON variables, lists, maps, presence, collection macros, core string checks, time values, arithmetic, comparisons, logic, and the conditional operator.

What you will do

You will run the prepared expression in the playground above, change one input at a time, and explain the result. Start in CEL only, then repeat the same rule in CEL + JSON.

How it works

filter() evaluates a boolean predicate for each item and returns a new list containing the matching original items. JSON numbers enter this playground as double, while remainder % accepts integers, so the JSON expression explicitly converts each number with int(number). The self-contained integer list needs no conversion.

Read the prepared example

The CEL + JSON rule is:

numbers.filter(number, int(number) % 2 == 0)

Its input is:

{
  "numbers": [1, 2, 3, 4, 5, 6]
}

The CEL only tab contains the values and the rule in one expression. The enabled cel.bind() extension keeps each name local to its final argument.

Evaluation step by step

  1. Each number is tested for remainder 0 after division by 2.
  2. Only 2, 4, and 6 satisfy the predicate.
  3. The result is a new three-item list.

Your task

  1. Run both modes and compare their displayed numeric types.
  2. Change the divisor from 2 to 3.
  3. Add 9 to the input and predict the new result before running.

Expected observation: With divisor 3, the matching values are 3, 6, and the added 9.

Common mistake

filter() does not transform values. The conversion here is only part of the test; matching JSON values remain doubles in the returned list.

Show the explanation

Because the playground maps JSON numbers to double, and % is defined for integer types.

Knowledge check

Why does the JSON version use int(number)?

Key takeaway

Use filter() to select original items. Make any type conversion required by the predicate explicit.

Sources

  • CEL-DEV — official CEL overview.
  • CEL-LANG — official CEL language definition.
  • CEL-GO-BIND — official documentation for the optional cel.bind() extension used by the self-contained tab.