Nodes/comfy-ovum/_.matcher
ComfyUI Node

_.matcher

Build a predicate that says 'got these attributes?' — the filter's best friend.

By sfinktah·Created about a year ago·Updated 10 months ago· 7
_.matcher
  • py_dict
  • attrs
  • *

_.matcher returns a predicate - a function that answers "does this object contain all of these key/value pairs?" Feed it {"model": "flux"} and you get back a function that returns true for any dict that has model set to flux. That predicate is exactly what you want to hand to a filter, or to any of the underscore nodes that take a predicate as their iteratee. It's the object-shorthand branch of _.iteratee made standalone.

What it is

Part of the ovum/underscore family in sfinktah/comfy-ovum, wrapping the matcher method of underscore3, a Python port of Underscore.js. The returned predicate checks every key in the attrs dict against the candidate object - via obj.get(key) for dicts, or attribute access for non-dicts - and only returns true when every pair matches.

Inputs and the quirk in them

The schema lists two inputs:

  • py_dict (type *) - the primary input.
  • attrs (type *) - described as the key/value pairs to match against, with JSON allowed.

Here's the thing I want you to understand before you trust that attrs socket: in the current code it doesn't actually map to a parameter. The port's matcher() takes no arguments - it builds the predicate from the object you feed into the primary input. So the attrs socket is effectively decorative in this version. Feed your attribute dict into py_dict instead, and the node works. This is exactly the kind of half-finished wiring the README warns about, and it's worth knowing so you don't spend an hour guessing why attrs seems to do nothing.

Output is typed * (ANY) - at runtime it's a Python function. Chain mode works: feed a _.CHAIN and get a chain back, resolved with _.value.

Where you'd use it

Filtering structured data. Build the matcher from {"tag": "sunset"}, then combine it with a filter-style node (or the underscore family's _.filter, which shares the predicate machinery) to keep only the entries that match. It's also useful for feature-flag style logic - "does this config object have these settings?" - as a gate on a conditional branch.

The caveat

Functions don't survive a save/reload as JSON, so the matcher you build lives only for the current session - rebuild it after reloading the workflow. And remember a matcher is a predicate, not a transformer: use it where a yes/no answer is what you need, and reach for _.map/_.mapObject when you want values changed.

Installing comfy-ovum

ComfyUI Manager: search for comfy-ovum, install, restart. Or by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/sfinktah/comfy-ovum
pip install -r comfy-ovum/requirements.txt

Restart and you're done. No model downloads, no CUDA - pure-Python utilities with a few small dependencies. Useful node, once you know to feed the matcher through the primary input.

Categoryovum/underscore

Inputs (2)

NameTypeDefaultDescription
py_dictopt*Primary input object (expected object). You can still pass any JSON-serializable value. Also accepts _.CHAIN to continue chaining.
attrsopt*attrs: JSON allowed for arrays/objects where applicable.

Outputs (1)

NameTypeDescription
**