> For the complete documentation index, see [llms.txt](https://docs.datajet-app.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.datajet-app.com/liquid/filters/contains_set.md).

# contains\_set

Checks if an array contains a value using optimized Set-based lookup. For large arrays (100+ items), this is significantly faster than the native `contains` operator, which uses O(n) linear search.

```liquid
{% assign all_skus = products | map: "sku" %}

{% if all_skus | contains_set: "ABC123" %}
  SKU exists in catalog
{% endif %}
```

#### Syntax

```liquid
{{ array | contains_set: value }}
```

| Parameter | Description         |
| --------- | ------------------- |
| `array`   | Array to search in  |
| `value`   | Value to search for |

#### Performance

| Array Size    | Native `contains`    | `contains_set` |
| ------------- | -------------------- | -------------- |
| 100 items     | O(100) per check     | O(1) per check |
| 10,000 items  | O(10,000) per check  | O(1) per check |
| 250,000 items | O(250,000) per check | O(1) per check |

The filter automatically caches the Set representation, so subsequent lookups on the same array are instant.

#### Examples

**Check if SKU exists in large inventory:**

```liquid
{% comment %} Fetch all existing SKUs from Shopify {% endcomment %}
{% assign all_skus = "[]" | parse %}
{% for n in (0..100) %}
  {% graphql query: sku_query, variables: vars as result %}
  {% for edge in result.productVariants.edges %}
    {% assign all_skus = all_skus | push: edge.node.sku %}
  {% endfor %}
  {% unless result.productVariants.pageInfo.hasNextPage %}{% break %}{% endunless %}
{% endfor %}

{% comment %} Check each import row against existing SKUs {% endcomment %}
{% for row in import_data %}
  {% if all_skus | contains_set: row.sku %}
    {% log "SKU already exists: " | append: row.sku %}
  {% else %}
    {% comment %} Create new product {% endcomment %}
  {% endif %}
{% endfor %}
```

**Filter items not in exclusion list:**

```liquid
{% assign excluded_tags = "sale,clearance,discontinued" | split: "," %}
{% assign products_to_process = "[]" | parse %}

{% for product in all_products %}
  {% assign dominated_value = false %}
  {% for tag in product.tags %}
    {% if excluded_tags | contains_set: tag %}
      {% assign dominated_value = true %}
      {% break %}
    {% endif %}
  {% endfor %}
  {% unless dominated_value %}
    {% assign products_to_process = products_to_process | push: product %}
  {% endunless %}
{% endfor %}
```

**Validate order items against allowed products:**

```liquid
{% assign allowed_product_ids = allowed_products | map: "id" %}

{% for line_item in order.line_items %}
  {% unless allowed_product_ids | contains_set: line_item.product_id %}
    {% log "Unauthorized product in order: " | append: line_item.title %}
    {% assign has_unauthorized = true %}
  {% endunless %}
{% endfor %}
```

#### When to Use

| Scenario                       | Recommended                                      |
| ------------------------------ | ------------------------------------------------ |
| Single lookup                  | Use native `contains`                            |
| Multiple lookups on same array | Use `contains_set`                               |
| Array with 100+ items          | Use `contains_set`                               |
| Small arrays (<100 items)      | Either works, `contains_set` has slight overhead |

#### Notes

* Works with strings too: `"hello world" | contains_set: "world"` returns `true`
* Returns `false` for `null` or `undefined` input arrays
