group_by_property

Groups an array by a property value in a single O(n) pass. Returns an object with groups (lookup by key) and keys (list of unique keys in order). This is faster than combining map, uniq, and multiple where calls.

{% assign grouped = products | group_by_property: "vendor" %}

{% for vendor in grouped.keys %}
  <h2>{{ vendor }} ({{ grouped.groups[vendor].size }} products)</h2>
  {% for product in grouped.groups[vendor] %}
    <p>{{ product.title }}</p>
  {% endfor %}
{% endfor %}

Syntax

{{ array | group_by_property: property }}
{{ array | group_by_property: "nested.property" }}
Parameter
Description

array

Array of objects to group

property

Property name to group by (supports dot notation for nested properties)

Return Value

Returns an object with two properties:

Property
Type
Description

groups

Object

Lookup object where keys are property values, values are arrays of items

keys

Array

List of unique property values in the order they were first encountered

Variants

group_by_property

Returns { groups: { key: [items] }, keys: [unique_keys] } format.

group_by_fast

Returns [{ name, items }, ...] format (same as native group_by but faster).

Examples

Process products by material (like the import script):

Group GraphQL edges by nested property:

Generate report by category:

Batch process variants by product:

Using group_by_fast for simple iteration:

Performance Comparison

For an array of 10,000 products with 500 unique materials:

Approach
Operations

map + uniq + where loop

O(10,000) + O(10,000) + O(10,000 × 500) = ~5,020,000

group_by_property

O(10,000) = 10,000

~500x faster for this use case.

Comparison with group_by

Feature

group_by

group_by_property / group_by_fast

Expression support

Yes ("price > 100")

No, property names only

Nested properties

Yes (via expression)

Yes (via dot notation)

Performance

Slower (expression eval)

Faster (direct access)

Output format

[{ name, items }]

{ groups, keys } or [{ name, items }]

Notes

  • Supports nested properties using dot notation: "node.status", "variant.sku"

  • Items with null or undefined property values are skipped

  • Keys are returned in the order they were first encountered

  • Returns { groups: {}, keys: [] } for empty or invalid input

  • Use group_by_fast if you need the same output format as native group_by

  • Use native group_by if you need expression evaluation (e.g., "price > 100")

Last updated