# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.datajet-app.com/liquid/filters/index_by.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
