Skip to content

Arrays & Collections Filters

Nimbu provides comprehensive array manipulation filters for filtering, sorting, grouping, and transforming collections.

Array Basics

size

Get array length:

liquid
{{ products | size }}
<!-- Output: 42 -->

{% if cart.items.size > 0 %}
  You have {{ cart.items.size }} items
{% endif %}

first

Get first element:

liquid
{{ products | first }}

{% assign featured = products | first %}

last

Get last element:

liquid
{{ articles | last }}

{% assign latest = blog.articles | last %}

Filtering Arrays

where

Filter array by property value:

liquid
{% assign published = articles | where: "published", true %}

{% assign featured_products = products | where: "featured", true %}

{% assign active_members = channels.team.all | where: "status", "active" %}

With Nested Properties:

liquid
{% assign expensive = products | where: "price", ">", 100 %}

where_exp

Filter with complex expressions:

liquid
{% assign recent = articles | where_exp: "article", "article.date > '2025-01-01'" %}

{% assign in_stock = products | where_exp: "p", "p.inventory > 0" %}

{% assign affordable = products | where_exp: "p", "p.price < 50" %}

Sorting Arrays

sort

Sort by property:

liquid
{% assign sorted_products = products | sort: "price" %}

{% assign alphabetical = team_members | sort: "name" %}

{% assign by_date = articles | sort: "published_at" %}

sort_natural

Case-insensitive alphabetical sort:

liquid
{% assign sorted = names | sort_natural %}

{% assign sorted_titles = articles | sort_natural: "title" %}

reverse

Reverse array order:

liquid
{% assign reversed = products | reverse %}

{% assign newest_first = articles | sort: "date" | reverse %}

Grouping and Organizing

group_by

Group array by property:

liquid
{% assign by_category = products | group_by: "category" %}

{% for group in by_category %}
  <h2>{{ group.name }}</h2>
  {% for product in group.items %}
    <p>{{ product.name }}</p>
  {% endfor %}
{% endfor %}

Result Structure:

liquid
[
  { name: "Clothing", items: [...] },
  { name: "Electronics", items: [...] }
]

group_by_exp

Group with expressions:

liquid
{% assign by_year = articles | group_by_exp: "article", "article.date | date: '%Y'" %}

{% for year_group in by_year %}
  <h2>{{ year_group.name }}</h2>
  {% for article in year_group.items %}
    <p>{{ article.title }}</p>
  {% endfor %}
{% endfor %}

{% assign by_price_range = products | group_by_exp: "p", "p.price | divided_by: 100 | times: 100" %}

Array Transformations

map

Extract property from all items:

liquid
{% assign product_names = products | map: "name" %}
<!-- Output: ["Product A", "Product B", "Product C"] -->

{% assign all_tags = articles | map: "tags" | flatten | uniq %}

{% assign prices = products | map: "price" %}

compact

Remove nil values:

liquid
{% assign clean_array = values | compact %}

{% assign valid_emails = users | map: "email" | compact %}

uniq

Remove duplicates:

liquid
{% assign unique = tags | uniq %}

{% assign all_categories = products | map: "category" | compact | uniq %}

flatten

Flatten nested arrays:

liquid
{% assign all_tags = articles | map: "tags" | flatten %}

{% assign flattened = nested_array | flatten %}

Array Slicing

slice

Extract portion of array:

liquid
{% assign first_three = products | slice: 0, 3 %}

{% assign items = array | slice: 5, 10 %}
<!-- Get 10 items starting from index 5 -->

offset / limit

Paginate arrays:

liquid
{% assign page_items = products | offset: 10 | limit: 20 %}
<!-- Skip first 10, take next 20 -->

{% assign recent = articles | limit: 5 %}

Set Operations

concat

Combine arrays:

liquid
{% assign combined = array1 | concat: array2 %}

{% assign all_items = featured_products | concat: new_products %}

join

Join array into string:

liquid
{{ tags | join: ", " }}
<!-- Output: "tag1, tag2, tag3" -->

{{ categories | join: " | " }}

split

Split string into array:

liquid
{% assign tags = "red,blue,green" | split: "," %}

{% assign words = sentence | split: " " %}

Practical Examples

Product Filtering and Sorting

liquid
<div class="product-grid">
  <!-- Get in-stock products, sorted by price -->
  {% assign available = products | where: "available", true %}
  {% assign sorted = available | sort: "price" %}

  {% for product in sorted %}
    <div class="product-card">
      <h3>{{ product.name }}</h3>
      <p class="price">{{ product.price | money_with_currency }}</p>
      <a href="{{ product.url }}">View Product</a>
    </div>
  {% endfor %}
</div>

Blog Archive by Year and Month

liquid
<div class="blog-archive">
  {% assign by_year = blog.articles | group_by_exp: "article", "article.published_at | date: '%Y'" %}

  {% for year_group in by_year | reverse %}
    <div class="year-section">
      <h2>{{ year_group.name }}</h2>

      {% assign by_month = year_group.items | group_by_exp: "article", "article.published_at | date: '%B'" %}

      {% for month_group in by_month %}
        <div class="month-section">
          <h3>{{ month_group.name }}</h3>

          <ul class="article-list">
            {% for article in month_group.items %}
              <li>
                <a href="{{ article.url }}">
                  {{ article.title }}
                </a>
                <time>{{ article.published_at | date: "%d" }}</time>
              </li>
            {% endfor %}
          </ul>
        </div>
      {% endfor %}
    </div>
  {% endfor %}
</div>

Category Navigation with Counts

liquid
<nav class="category-filter">
  {% assign by_category = products | group_by: "category" %}

  <ul class="category-list">
    {% for group in by_category | sort: "name" %}
      <li>
        <a href="?category={{ group.name | parameterize }}">
          {{ group.name }}
          <span class="count">({{ group.items.size }})</span>
        </a>
      </li>
    {% endfor %}
  </ul>
</nav>
liquid
<div class="related-products">
  <h3>You May Also Like</h3>

  {% assign same_category = products | where: "category", product.category %}
  {% assign others = same_category | where_exp: "p", "p.id != product.id" %}
  {% assign related = others | limit: 4 %}

  <div class="product-grid">
    {% for item in related %}
      <div class="product-card">
        <img src="{{ item.images.first.url | filter, width: '300px' }}" alt="{{ item.name }}">
        <h4>{{ item.name }}</h4>
        <p class="price">{{ item.price | money_with_currency }}</p>
      </div>
    {% endfor %}
  </div>
</div>

Tag Cloud with Frequency

liquid
<div class="tag-cloud">
  {% assign all_tags = articles | map: "tags" | flatten %}
  {% assign unique_tags = all_tags | uniq | sort_natural %}

  {% for tag in unique_tags %}
    {% assign count = all_tags | where: tag | size %}

    <a
      href="/blog/tag/{{ tag | parameterize }}"
      class="tag"
      style="font-size: {{ count | times: 2 | plus: 12 }}px;">
      {{ tag }} ({{ count }})
    </a>
  {% endfor %}
</div>

Price Range Filtering

liquid
<div class="price-ranges">
  {% assign ranges = products | group_by_exp: "p", "p.price | divided_by: 50 | times: 50" %}

  <ul class="range-list">
    {% for range in ranges | sort: "name" %}
      {% assign min = range.name %}
      {% assign max = range.name | plus: 49 %}

      <li>
        <a href="?price_min={{ min }}&price_max={{ max }}">
          {{ min | money_without_currency }} - {{ max | money_without_currency }}
          <span class="count">({{ range.items.size }})</span>
        </a>
      </li>
    {% endfor %}
  </ul>
</div>

Pagination with Array Slicing

liquid
{% assign page = params.page | default: 1 | to_i %}
{% assign per_page = 12 %}
{% assign offset = page | minus: 1 | times: per_page %}

{% assign page_items = products | offset: offset | limit: per_page %}
{% assign total_pages = products.size | divided_by: per_page | ceil %}

<div class="products">
  {% for product in page_items %}
    <!-- Product card -->
  {% endfor %}
</div>

<nav class="pagination">
  {% if page > 1 %}
    <a href="?page={{ page | minus: 1 }}">Previous</a>
  {% endif %}

  {% for i in (1..total_pages) %}
    <a href="?page={{ i }}" {% if i == page %}class="active"{% endif %}>{{ i }}</a>
  {% endfor %}

  {% if page < total_pages %}
    <a href="?page={{ page | plus: 1 }}">Next</a>
  {% endif %}
</nav>
liquid
{% assign featured = products | where: "featured", true %}
{% assign regular = products | where: "featured", false %}
{% assign all_sorted = featured | concat: regular %}

<div class="product-list">
  {% for product in all_sorted %}
    <div class="product {% if product.featured %}featured{% endif %}">
      <!-- Product display -->
    </div>
  {% endfor %}
</div>

Team Directory by Department

liquid
<div class="team-directory">
  {% assign by_department = channels.team.all | group_by: "department" %}

  {% for dept_group in by_department | sort: "name" %}
    <section class="department">
      <h2>{{ dept_group.name }}</h2>

      {% assign sorted_members = dept_group.items | sort: "name" %}

      <div class="team-grid">
        {% for member in sorted_members %}
          <div class="team-card">
            <img src="{{ member.photo.url | filter, width: '200px', height: '200px', cropping: 'fill', gravity: 'face' }}" alt="{{ member.name }}">
            <h3>{{ member.name }}</h3>
            <p class="role">{{ member.role }}</p>
            <p class="email">{{ member.email }}</p>
          </div>
        {% endfor %}
      </div>
    </section>
  {% endfor %}
</div>

Best Practices

1. Chain Filters Efficiently

Order operations for performance:

liquid
<!-- ✅ Good: Filter before sort -->
{% assign results = products | where: "available", true | sort: "price" %}

<!-- ❌ Bad: Sort before filter (wastes sorting) -->
{% assign results = products | sort: "price" | where: "available", true %}

2. Use where_exp for Complex Conditions

liquid
<!-- ✅ Good: Complex filtering -->
{% assign affordable_in_stock = products | where_exp: "p", "p.price < 100 and p.inventory > 0" %}

<!-- ❌ Bad: Multiple where calls -->
{% assign temp = products | where: "price", "<", 100 %}
{% assign result = temp | where: "inventory", ">", 0 %}

3. Cache Expensive Operations

liquid
<!-- ✅ Good: Cache grouped results -->
{% assign by_category = products | group_by: "category" %}
<!-- Reuse by_category multiple times -->

<!-- ❌ Bad: Repeat grouping -->
{% for category in products | group_by: "category" %}...{% endfor %}
{% for category in products | group_by: "category" %}...{% endfor %}

Next Steps

Master array and collection manipulation in Nimbu themes!