← Back to Documentation

Set Operations

Compute intersections, differences, and unions on lists, strings, and objects. Polymorphic operations that work seamlessly across different data types.

Polymorphic Design

The same operations work on Lists, Strings, and Objects. ARO automatically applies the appropriate comparison logic for each type.

intersect
difference
union

Operations Overview

Operation Description Syntax
intersect Elements present in both A and B <Compute> the <result: intersect> from <a> with <b>.
difference Elements in A but not in B <Compute> the <result: difference> from <a> with <b>.
union All unique elements from both <Compute> the <result: union> from <a> with <b>.

List Operations

The most common use case. Find common elements, differences, or combine lists:

<Create> the <list-a> with [2, 3, 5].
<Create> the <list-b> with [1, 2, 3, 4].

(* Find elements in both lists *)
<Compute> the <common: intersect> from <list-a> with <list-b>.
(* Result: [2, 3] *)

(* Find elements in A not in B *)
<Compute> the <only-in-a: difference> from <list-a> with <list-b>.
(* Result: [5] *)

(* Combine all unique elements *)
<Compute> the <all: union> from <list-a> with <list-b>.
(* Result: [2, 3, 5, 1, 4] *)

Multiset Semantics

When lists contain duplicates, intersect preserves duplicates up to the minimum count in either list:

<Create> the <a> with [1, 2, 2, 3].
<Create> the <b> with [2, 2, 2, 4].

<Compute> the <common: intersect> from <a> with <b>.
(* Result: [2, 2] - two 2s appear in both *)

String Operations

Set operations work at the character level for strings:

(* Find common characters *)
<Compute> the <shared: intersect> from "hello" with "bello".
(* Result: "ello" *)

(* Find unique characters in first string *)
<Compute> the <unique: difference> from "hello" with "bello".
(* Result: "h" *)

(* All unique characters *)
<Compute> the <combined: union> from "hello" with "bello".
(* Result: "hellob" *)

Object Operations (Deep Comparison)

For objects, set operations perform deep recursive comparison. Only key-value pairs that match exactly are included in intersections:

<Create> the <obj-a> with {
    name: "Alice",
    age: 30,
    address: { city: "NYC", zip: "10001" }
}.

<Create> the <obj-b> with {
    name: "Alice",
    age: 31,
    address: { city: "NYC", state: "NY" }
}.

(* Find matching key-value pairs *)
<Compute> the <common: intersect> from <obj-a> with <obj-b>.
(* Result: { name: "Alice", address: { city: "NYC" } } *)

(* Find differences *)
<Compute> the <diff: difference> from <obj-a> with <obj-b>.
(* Result: { age: 30, address: { zip: "10001" } } *)

Type Behavior Summary

Operation Lists Strings Objects
intersect Elements in both (multiset) Chars in both (order preserved) Keys with matching values (recursive)
difference In A, not in B Chars in A, not in B Keys/values in A, not matching B
union A preserved + unique from B A preserved + unique from B Merge keys (A wins conflicts)

Related: Filter with not in

The Filter action also supports set membership testing with in and not in operators. These accept either CSV strings or array variables:

(* Create an exclusion list *)
<Create> the <exclude-statuses> with ["cancelled", "refunded"].

(* Filter using array variable *)
<Filter> the <active-orders> from the <orders>
    where <status> not in <exclude-statuses>.

(* Or use CSV string syntax *)
<Filter> the <pending> from the <orders>
    where <status> in "pending,processing".

Complete Example

Here's a practical example comparing two product catalogs:

(Catalog Comparison: Inventory) {
    (* Two product ID lists *)
    <Create> the <warehouse-a> with ["SKU-001", "SKU-002", "SKU-005"].
    <Create> the <warehouse-b> with ["SKU-001", "SKU-003", "SKU-004"].

    (* Find products in both warehouses *)
    <Compute> the <in-both: intersect> from <warehouse-a> with <warehouse-b>.

    (* Find products only in warehouse A *)
    <Compute> the <only-in-a: difference> from <warehouse-a> with <warehouse-b>.

    (* Find products only in warehouse B *)
    <Compute> the <only-in-b: difference> from <warehouse-b> with <warehouse-a>.

    (* Get complete inventory *)
    <Compute> the <all-products: union> from <warehouse-a> with <warehouse-b>.

    <Return> an <OK: status> with {
        in-both: <in-both>,
        exclusive-a: <only-in-a>,
        exclusive-b: <only-in-b>,
        total-inventory: <all-products>
    }.
}

Learn More

See the full set operations specification in ARO-0042: Set Operations.