# Filtering and querying, in practice

Source: https://libtmux.org/en/lua/latest/guides/querying-and-filtering/

> Filter tmux objects, require one match, and choose where a query runs.

Find sessions, windows, or panes with collection filters and exactly-one
lookups. [Filtering and queries](/concepts/queries/) explains the result-count
contracts and the choice between local and tmux-side filtering. This guide adds
examples for common queries.

## Filling in the rest of the cardinality table

| Port | Collection filter | Exactly-one | Empty | Several |
|------|--------------------|--------------|-------|---------|
| Go | `tmuxq.Where(values, predicate)` | `tmuxq.ExactlyOne(values, predicate)` | `tmuxq.ErrNoMatch` | `tmuxq.ErrMultipleMatches` |
| Rust | `.iter().matching(&expr)` | `.exactly_one()` | prints via the error's `Display` | same, one error type covers both |
| C++ | pipe a range into [`libtmux::matching(expr)`](/cxx/latest/reference/libtmux-matching/) | `libtmux::exactly_one(range)` | `.error()` says which way it went wrong | same call, same error type |

Go's `ExampleExactlyOne` in `tmuxq/example_test.go` checks the result with `go
test` and `// Output:` assertions:

Rust's is `examples/find.rs`, run via `cargo run --example find`:

C++'s is quoted straight from `examples/05-readme.cpp`'s `cardinality`
region into `README.md`, and `tools/docs/check_readme.py` fails the build
if the two ever disagree:

For .NET and Swift result-count handling, consult the port reference. The
examples here demonstrate .NET's `IEnumerable<T>.Matching<T>(expression)`
returning an `IReadOnlyList<Session>` and Swift's `hasSession(_:)` returning a
`Bool`. The latter checks existence; see [Attaching to
tmux](../attaching-to-tmux/#finding-a-session-instead-of-always-creating-one).

## Declarative filters that travel, beyond Python and TypeScript

[Filtering and queries](/concepts/queries/) covers Python's `.filter()`
lookups and TypeScript's `.where()` documents. Two more ports build the same
"a query is data, not code" idea, verified against their own README:

Sources: .NET's is `src/LibTmux/README.md`, "Filtering." Swift's is
`Examples/Sources/ExampleCode/Filtering.swift`, matched against the README
by `Scripts/check_examples.py`.

## Case-insensitive matching

For case-insensitive matching in Java, .NET, Go, Rust, and C++, consult the port
reference. Sources for the examples above: Python's lookup is covered in
[Filtering and queries](../../concepts/queries/); TypeScript's is in
`README.md`, "What querying looks like"; Swift's is in
`Examples/Sources/ExampleCode/Filtering.swift`.

## Push the filter into tmux, or read once and filter locally

Use a tmux-side filter to reduce the rows returned, or query a snapshot when you
need several answers from one read. [Filtering and queries](/concepts/queries/)
compares Python's `search_sessions()` with `.filter()`, and Go's `SearchPanes`
with a snapshot plus `tmuxq.Where`. Check the required tmux version. Unknown
format tokens expand to empty values, so validate an unexpectedly empty search
before concluding that no objects match.

## Where to go next

- [Attach and send keys](/examples/attach-and-send-keys/): its
  "Finding an existing session instead" section is this guide's recipes
  applied to one concrete lookup.
- [Testing with libtmux](../testing-with-libtmux/): most of the fixtures
  there hand you a server with exactly one thing on it, which is precisely
  when an exactly-one query is the right tool instead of a filter you then
  index into.
