Nodes/comfy-ovum/_.inject
ComfyUI Node

_.inject

Reduce by its old name, and the WIP edge you'll notice immediately

By sfinktah·Created about a year ago·Updated 10 months ago· 7
_.inject
  • obj
  • memo
  • *

_.inject is _.reduce by its old functional-programming name - foldl, if you're a Haskell person. Reduce is the operation that collapses a list into a single value: sum the numbers, join the strings, accumulate a dict from a list of records. Underscore.js shipped it as inject for ages, and this Python port keeps the legacy name alongside _.reduce.

Here's the honest part: this node is where the pack's "work in progress" warning becomes visible. The generated schema exposes only two inputs - obj and memo - and neither of those is the function that does the reducing. A fold without its fold function is just a box with a starting value, which is a real limitation.

How it works

The underlying method builds up a single result by threading an accumulator through each element:

def reduce(self, iteratee, memo=None):
    # iteratee takes (memo, value, index) and returns memo
    if memo is None:
        memo = []
    ...

If no memo is supplied it defaults to [] - a list accumulator - and the iteratee (the (memo, value, index) function) is what decides how the fold behaves. inject is just this same method under its alias.

The inputs that matter

  • obj - the primary input (*), the collection to fold. Also accepts a _.CHAIN to continue chaining.
  • memo - the starting accumulator. Typed *, so it can be a number, a list, or an empty dict. This is the only real control you get on this node.

Output is a single * - the accumulated result, untyped.

The missing piece: there's no iteratee input on this node's schema. The generator produces a sibling _.reduce node (same pack, same category) that does expose iteratee plus an iteratee_json editor. So if you want a working fold, reach for _.reduce and treat _.inject as the legacy stub. That asymmetry is a perfect example of what "auto-generated, still WIP" means in practice - the two names are the same operation, but they got different schemas.

Where you'd actually use it

Once you have _.reduce with its iteratee, folding is genuinely powerful in ComfyUI: accumulate a list of seeds into a checksum, build a dict from a list of metadata records, join strings without a dedicated join node. _.inject specifically is the one you'll use when you want the default memo behavior (accumulating into a list) and don't need a custom function.

Installing

Part of comfy-ovum (MIT). ComfyUI Manager → search comfy-ovum → install → restart, or:

cd ComfyUI/custom_nodes
git clone https://github.com/sfinktah/comfy-ovum

Underscore nodes need nothing extra - they run on the underscore3 port bundled in the repo. Pack-wide requirements.txt includes pymediainfo (system libmediainfo on Linux), tomli-w, requests, braceexpand, pillow, numpy, markdown-it-py, aiohttp.

Gotchas

The pack's own README calls the underscore family "an absolute disaster to use in production," and _.inject is the node where I'd most believe it: the missing iteratee input is a genuine rough edge, not a doc quirk. Keep it for experiments and simple default-memo folds; use _.reduce when you actually need control over the fold function.

Categoryovum/underscore

Inputs (2)

NameTypeDefaultDescription
objopt*Primary input object. Also accepts _.CHAIN to continue chaining.
memoopt*memo: JSON allowed for arrays/objects where applicable.

Outputs (1)

NameTypeDescription
**