# where\_exp

Filters an array using a Liquid expression. Unlike `where`, which matches a property to a value, `where_exp` lets you write arbitrary conditions using the full Liquid expression syntax.

```liquid
{% assign expensive = products | where_exp: "p", "p.price > 100" %}
{% log "Expensive products: " | append: expensive.size %}
```

#### Syntax

```liquid
{{ array | where_exp: item_name, expression }}
```

| Parameter    | Description                                              |
| ------------ | -------------------------------------------------------- |
| `array`      | Array of objects to filter                               |
| `item_name`  | Variable name for the current item inside the expression |
| `expression` | Liquid expression that evaluates to truthy/falsy         |

#### Return Value

Returns an array containing only the items for which the expression evaluated to a truthy value.

#### Examples

**Filter products above a price threshold:**

```liquid
{% assign expensive = products | where_exp: "p", "p.price > 50" %}
{% for product in expensive %}
  {% log product.title | append: ": $" | append: product.price %}
{% endfor %}
```

**Filter orders with a specific tag:**

```liquid
{% assign vip_orders = orders | where_exp: "o", "o.tags contains 'VIP'" %}
{% log "VIP orders: " | append: vip_orders.size %}
```

**Filter with multiple conditions:**

```liquid
{% assign matches = products | where_exp: "p", "p.vendor == 'Nike' and p.product_type == 'Shoes'" %}
{% log "Nike shoes: " | append: matches.size %}
```

**Filter out empty values:**

```liquid
{% assign with_sku = variants | where_exp: "v", "v.sku != blank" %}
{% log "Variants with SKU: " | append: with_sku.size %}
```

**Filter by numeric comparison:**

```liquid
{% assign low_stock = variants | where_exp: "v", "v.inventory_quantity < 10" %}
{% for variant in low_stock %}
  {% log variant.sku | append: ": " | append: variant.inventory_quantity | append: " remaining" %}
{% endfor %}
```

**Filter by negation:**

```liquid
{% assign not_archived = products | where_exp: "p", "p.status != 'ARCHIVED'" %}
{% log "Active products: " | append: not_archived.size %}
```

**Combine with other filters:**

```liquid
{% assign active_expensive = products | where_exp: "p", "p.status == 'ACTIVE'" | where_exp: "p", "p.price > 100" %}
{% assign total = active_expensive | map: "price" | sum %}
{% log "Total value of active expensive products: $" | append: total %}
```

#### Comparison with `where`

| Feature             | `where`                     | `where_exp`                                           |
| ------------------- | --------------------------- | ----------------------------------------------------- |
| Syntax              | `where: "status", "active"` | `where_exp: "p", "p.status == 'active'"`              |
| Equality only       | Yes                         | No — supports `>`, `<`, `contains`, `and`, `or`, etc. |
| Multiple conditions | No (chain multiple `where`) | Yes (use `and` / `or` in expression)                  |
| Negation            | No                          | Yes (`!=`, `unless`-style logic)                      |

#### Notes

* The `item_name` parameter defines how you reference each item inside the expression
* The expression supports all Liquid operators: `==`, `!=`, `>`, `<`, `>=`, `<=`, `contains`, `and`, `or`
* Returns all matching items — to get only the first match, use `find_exp` instead
* Can be chained: `| where_exp: "p", "..." | where_exp: "p", "..."`
* See also: `where`, `find_exp`, `group_by_exp`
