Arrays & Collections Filters
Filter, sort, group, and manipulate arrays and collections with powerful helpers
Nimbu provides comprehensive array manipulation filters for filtering, sorting, grouping, and transforming collections.
Array Basics
size
Get array length:
{{ products | size }}
<!-- Output: 42 -->
{% if cart.items.size > 0 %}
You have {{ cart.items.size }} items
{% endif %}first
Get first element:
{{ products | first }}
{% assign featured = products | first %}last
Get last element:
{{ articles | last }}
{% assign latest = blog.articles | last %}Filtering Arrays
where
Filter array by property value:
{% 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:
{% assign expensive = products | where: "price", ">", 100 %}where_exp
Filter with complex expressions:
{% 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:
{% 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:
{% assign sorted = names | sort_natural %}
{% assign sorted_titles = articles | sort_natural: "title" %}reverse
Reverse array order:
{% assign reversed = products | reverse %}
{% assign newest_first = articles | sort: "date" | reverse %}Grouping and Organizing
group_by
Group array by property:
{% 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:
[
{ name: "Clothing", items: [...] },
{ name: "Electronics", items: [...] }
]group_by_exp
Group with expressions:
{% 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:
{% 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:
{% assign clean_array = values | compact %}
{% assign valid_emails = users | map: "email" | compact %}uniq
Remove duplicates:
{% assign unique = tags | uniq %}
{% assign all_categories = products | map: "category" | compact | uniq %}flatten
Flatten nested arrays:
{% assign all_tags = articles | map: "tags" | flatten %}
{% assign flattened = nested_array | flatten %}Array Slicing
slice
Extract portion of array:
{% assign first_three = products | slice: 0, 3 %}
{% assign items = array | slice: 5, 10 %}
<!-- Get 10 items starting from index 5 -->offset / limit
Paginate arrays:
{% assign page_items = products | offset: 10 | limit: 20 %}
<!-- Skip first 10, take next 20 -->
{% assign recent = articles | limit: 5 %}Set Operations
concat
Combine arrays:
{% assign combined = array1 | concat: array2 %}
{% assign all_items = featured_products | concat: new_products %}join
Join array into string:
{{ tags | join: ", " }}
<!-- Output: "tag1, tag2, tag3" -->
{{ categories | join: " | " }}split
Split string into array:
{% assign tags = "red,blue,green" | split: "," %}
{% assign words = sentence | split: " " %}Practical Examples
Product Filtering and Sorting
<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
<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
<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>Related Products
<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
<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
<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
{% 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>Featured Items First
{% 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
<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:
<!-- ✅ 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
<!-- ✅ 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
<!-- ✅ 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
- Text Formatting - String manipulation
- Channels - Working with custom content
- Global Variables - Array variables reference
- Performance - Optimization techniques
Master array and collection manipulation in Nimbu themes!