Nodes/comfyui-qbug-batch/Cross Join Selector
ComfyUI Node

Cross Join Selector

Every combination, one queue at a time

By Q-Bug4·Created about a year ago·Updated about a year ago· 2
Cross Join Selector
    • output_1
    • output_2
    • output_3
    • output_4
    • output_5
    separator,
    resetfalse
    input_1
    limit_10
    input_2
    limit_20
    input_3
    limit_30
    input_4
    limit_40
    input_5
    limit_50

    Cross Join Selector is the node you reach for the moment you think "I want to generate every character × every background × every style and compare them all" and realize you don't want to click through that by hand. It's the flagship node of the qbug-batch pack, and it does one job: act as a stateful nested-loop iterator over up to five comma-separated lists. Each time your workflow runs, it hands back one item from each list - odometer style - so you can queue up a batch and let ComfyUI chew through the entire cross product while you go make coffee.

    How it works

    The mechanism is a lot dumber and more reliable than it sounds. On every execution the node splits each input string on the separator, strips whitespace, and drops empties. It keeps an index and a count for each list in memory, then advances the innermost one like a car odometer: when the inner list hits its limit (or runs out of items), it carries up to the next list out, and when every list has finished its pass it wraps back to all zeros and starts over - so a long queue just keeps cycling until you stop it.

    Two implementation details matter in practice. First, the node declares IS_CHANGED to return the current time, which tells ComfyUI to never cache its output. That's not an accident: if ComfyUI decided "same inputs, same result, skip it," the iterator would never advance and you'd get the same combination on every run. Second, its state lives in a class-level dictionary keyed by the exact input lists plus their limits - which is where the traps live (below).

    The inputs that matter

    • input_1 (required) - your first list, comma-separated. input_2 through input_5 are optional extras.
    • limit_n - how many items from list n get walked through before carrying to the next list. 0 means no limit, i.e. iterate the whole list. The README's example: input_1 = pic1,pic2,pic3 with no limit, input_2 = 1,2,3,...,10 with limit_2 = 3 gives you every pic, each paired with three values from the second list.
    • separator - the split character, default comma. Keep it the same as whatever produced the input strings.
    • reset - flip to true once and the iteration rewinds to the start.

    The outputs are output_1 through output_5: the item currently selected from each list. Wire them into a Text Concatenate feeding your prompt, into a filename, or anywhere else a string lands. Note that empty inputs are skipped and just leave their output slot as "" - so if you only use two lists, only output_1 and output_2 carry real data.

    Installing it

    It ships with the whole qbug-batch pack, and this one is as clean as ComfyUI installs get: no requirements.txt, no model downloads, no API keys. Install via ComfyUI Manager (search "qbug-batch") or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/Q-Bug4/comfyui-qbug-batch
    

    Then restart ComfyUI. The repo has a ready-made crossjoin-example.json workflow you can drag in to see it wired correctly.

    The traps

    The big one: state is shared across every selector node with identical inputs and limits. Because the state dictionary is keyed only by "the input lists + their limits," two Cross Join Selector nodes in the same workflow that have the same lists and limits are literally the same iterator - they advance in lockstep, so one of them will look like it's skipping items. Differentiate them with a different limit value or a dummy element in one list.

    Second, state lives in RAM. Restart ComfyUI mid-batch and the whole iteration starts over from the beginning - fine for a short run, annoying when you're 400 images deep. There's also no persistence across sessions, so treat it as an "in this queue" tool, not a checkpoint.

    Third, remember what it is: on a single run you only get the first combination. The whole point is that you queue the workflow many times and let the iterator walk through the space. If you're not queueing a batch, this node is doing very little for you.

    It's a string-in, string-out utility, which makes it oddly portable - pair it with this pack's ListFiles node to iterate over a folder of prompts or reference images, and you've got a whole batch rig with two nodes and zero Python.

    Categoryselector

    Inputs (12)

    NameTypeDefaultDescription
    separatorSTRING,
    resetBOOLEANfalse
    input_1STRING
    limit_1INT00–999999
    input_2optSTRING
    limit_2optINT00–999999
    input_3optSTRING
    limit_3optINT00–999999
    input_4optSTRING
    limit_4optINT00–999999
    input_5optSTRING
    limit_5optINT00–999999

    Outputs (5)

    NameTypeDescription
    output_1STRING
    output_2STRING
    output_3STRING
    output_4STRING
    output_5STRING