> 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/index_by.md).

# index\_by

Creates a lookup object from an array, indexed by a specified property. This enables O(1) direct access to items instead of O(n) array searching with `where` or `find`.

```liquid
{% assign products_by_sku = products | index_by: "sku" %}

{% comment %} O(1) direct access instead of O(n) search {% endcomment %}
{% assign product = products_by_sku["ABC123"] %}
```

#### Syntax

```liquid
{{ array | index_by: property }}
{{ array | index_by: "nested.property" }}
```

| Parameter  | Description                                                                         |
| ---------- | ----------------------------------------------------------------------------------- |
| `array`    | Array of objects to index                                                           |
| `property` | Property name to use as the index key (supports dot notation for nested properties) |

#### Variants

**index\_by**

Returns an object where each key maps to a single item. If multiple items share the same key, the last one wins.

```liquid
{% assign users_by_email = users | index_by: "email" %}
{% assign user = users_by_email["john@example.com"] %}
```

**index\_by\_all**

Returns an object where each key maps to an array of all items with that key. Useful when multiple items can share the same key.

```liquid
{% assign orders_by_status = orders | index_by_all: "status" %}
{% assign pending_orders = orders_by_status["pending"] %}
{% log "Pending orders: " | append: pending_orders.size %}
```

#### Examples

**Fast variant lookup by SKU:**

```liquid
{% comment %} Build index once {% endcomment %}
{% assign variants_by_sku = shopify_variants | index_by: "sku" %}

{% comment %} Process import file with O(1) lookups {% endcomment %}
{% for row in import_data %}
  {% assign existing_variant = variants_by_sku[row.sku] %}
  {% if existing_variant %}
    {% comment %} Update existing variant {% endcomment %}
    {% log "Updating: " | append: row.sku %}
  {% else %}
    {% comment %} Create new variant {% endcomment %}
    {% log "Creating: " | append: row.sku %}
  {% endif %}
{% endfor %}
```

**Index GraphQL edges by nested property:**

```liquid
{% comment %} GraphQL returns edges with node wrapper {% endcomment %}
{% assign edges_by_id = result.products.edges | index_by: "node.legacyResourceId" %}

{% comment %} Direct access using product ID {% endcomment %}
{% assign product_edge = edges_by_id["12345"] %}
```

**Group orders by customer for batch processing:**

```liquid
{% assign orders_by_customer = orders | index_by_all: "customer.id" %}

{% for customer_id in customer_ids %}
  {% assign customer_orders = orders_by_customer[customer_id] %}
  {% if customer_orders %}
    {% log "Customer " | append: customer_id | append: " has " | append: customer_orders.size | append: " orders" %}

    {% comment %} Process all orders for this customer {% endcomment %}
    {% for order in customer_orders %}
      {% comment %} ... {% endcomment %}
    {% endfor %}
  {% endif %}
{% endfor %}
```

**Match inventory levels to variants:**

```liquid
{% comment %} Index variants by barcode for inventory matching {% endcomment %}
{% assign variants_by_barcode = all_variants | index_by: "barcode" %}

{% for inventory_row in inventory_file %}
  {% assign variant = variants_by_barcode[inventory_row.ean] %}
  {% if variant %}
    {% comment %} Update inventory for this variant {% endcomment %}
    {% assign inventory_item_id = variant.inventory_item_id %}
    {% comment %} ... update logic ... {% endcomment %}
  {% else %}
    {% log "No variant found for barcode: " | append: inventory_row.ean %}
  {% endif %}
{% endfor %}
```

**Create lookup for metafield values:**

```liquid
{% assign metafields_by_key = product.metafields | index_by: "key" %}

{% assign color = metafields_by_key["color"].value %}
{% assign material = metafields_by_key["material"].value %}
{% assign care_instructions = metafields_by_key["care_instructions"].value %}
```

#### Performance Comparison

| Operation     | Without index\_by | With index\_by |
| ------------- | ----------------- | -------------- |
| Build index   | -                 | O(n) once      |
| Single lookup | O(n) with `where` | O(1)           |
| 100 lookups   | O(n × 100)        | O(n) + O(100)  |
| 1000 lookups  | O(n × 1000)       | O(n) + O(1000) |

For an array of 10,000 items with 500 lookups:

* Without index: 10,000 × 500 = 5,000,000 operations
* With index: 10,000 + 500 = 10,500 operations

#### Notes

* Supports nested properties using dot notation: `"node.sku"`, `"variant.barcode"`
* Returns empty object `{}` for `null`, `undefined`, or non-array input
* Items with `null` or `undefined` key values are skipped
* For `index_by`: if multiple items have the same key, the last item is kept
* For `index_by_all`: all items with the same key are collected into an array
