Skip to main content

Overview

The Collection class wraps arrays and provides a fluent, chainable API for filtering, sorting, transforming, and aggregating data. It’s inspired by Laravel Collections and is returned by QueryBuilder and Model queries.

Creating Collections

// From query results
const users = db.table('Users').get(); // Returns a Collection

// Manually create
const collection = new Collection([1, 2, 3, 4, 5]);
const users = Collection.make([{name: 'John'}, {name: 'Jane'}]);

Static Constructors

Create a new collection from an array.
const collection = Collection.make([1, 2, 3, 4, 5]);
items
array
required
Array of items to wrap
return
Collection
Returns a new Collection instance
Wrap a value in a collection.
const collection = Collection.wrap([1, 2, 3]); // Collection
const single = Collection.wrap(42); // Collection with [42]
const existing = Collection.wrap(otherCollection); // Returns same collection
value
any
required
Value to wrap (array, collection, or single value)
return
Collection
Returns a Collection instance
Create a collection by invoking a callback n times.
const squares = Collection.times(5, i => i * i);
// Collection: [0, 1, 4, 9, 16]
count
number
required
Number of times to invoke callback
callback
function
required
Function called with index (0-based)
return
Collection
Returns a new Collection with generated items
Create a collection of numbers in a range.
const numbers = Collection.range(1, 5);
// Collection: [1, 2, 3, 4, 5]
from
number
required
Start of range (inclusive)
to
number
required
End of range (inclusive)
return
Collection
Returns a new Collection with range values

Basic Operations

Get all items as a plain array.
const users = User.where('status', 'active').get();
const array = users.all();
return
array
Returns the underlying array
Get the number of items.
const count = collection.count();
console.log(`${count} items`);
return
number
Returns the item count
Check if the collection is empty.
if (users.isEmpty()) {
  console.log('No users found');
}
return
boolean
Returns true if empty, false otherwise
Check if the collection is not empty.
if (users.isNotEmpty()) {
  console.log('Users found');
}
return
boolean
Returns true if not empty, false otherwise
Get the first item, optionally matching a callback.
const first = users.first();
const admin = users.first(user => user.role === 'admin');
callback
function
Optional filter function
return
any|null
Returns the first matching item or null
Get the last item, optionally matching a callback.
const last = users.last();
const lastActive = users.last(user => user.status === 'active');
callback
function
Optional filter function
return
any|null
Returns the last matching item or null

Filtering

Filter items using a callback.
const activeUsers = users.filter(user => user.status === 'active');
const expensive = products.filter(p => p.price > 100);
callback
function
required
Function that returns true to keep the item
return
Collection
Returns a new filtered Collection
Filter items where a property matches a value.
const activeUsers = users.where('status', 'active');
const highValueOrders = orders.where('total', '>', 1000);
key
string
required
Property name (supports dot notation for nested properties)
operator
string
Comparison operator: ==, ===, !=, !==, <, >, <=, >= (defaults to ===)
value
any
required
Value to compare against
return
Collection
Returns a new filtered Collection
Filter items where property value is in an array.
const users = collection.whereIn('role', ['admin', 'moderator']);
key
string
required
Property name
values
array
required
Array of values to match
return
Collection
Returns a new filtered Collection
Filter items where property value is not in an array.
const users = collection.whereNotIn('status', ['banned', 'suspended']);
key
string
required
Property name
values
array
required
Array of values to exclude
return
Collection
Returns a new filtered Collection
Filter items where property is null.
const incomplete = orders.whereNull('completed_at');
key
string
required
Property name
return
Collection
Returns a new filtered Collection
Filter items where property is not null.
const verified = users.whereNotNull('verified_at');
key
string
required
Property name
return
Collection
Returns a new filtered Collection

Transformation

Transform each item using a callback.
const names = users.map(user => user.name);
const doubled = numbers.map(n => n * 2);
callback
function
required
Function to transform each item
return
Collection
Returns a new Collection with transformed items
Map and flatten the results.
const allTags = posts.flatMap(post => post.tags);
callback
function
required
Function that returns an array for each item
return
Collection
Returns a new flattened Collection
Extract values for a given property.
const emails = users.pluck('email');
const nested = users.pluck('profile.address.city'); // Supports dot notation
key
string
required
Property name (supports dot notation)
return
Collection
Returns a new Collection of property values
Get unique items, optionally by a property.
const uniqueNumbers = Collection.make([1, 2, 2, 3, 3, 4]).unique();
const uniqueStatuses = users.unique('status');
key
string
Optional property name to determine uniqueness
return
Collection
Returns a new Collection with duplicates removed

Sorting

Sort items using an optional comparator.
const sorted = Collection.make([3, 1, 2]).sort();
const custom = collection.sort((a, b) => b.priority - a.priority);
callback
function
Optional comparator function
return
Collection
Returns a new sorted Collection
Sort items by a property.
const sorted = users.sortBy('name');
const desc = users.sortBy('created_at', 'desc');
key
string
required
Property name to sort by
direction
string
default:"asc"
Sort direction: asc or desc
return
Collection
Returns a new sorted Collection
Sort items by a property in descending order.
const latest = posts.sortByDesc('created_at');
key
string
required
Property name to sort by
return
Collection
Returns a new sorted Collection (descending)
Reverse the order of items.
const reversed = collection.reverse();
return
Collection
Returns a new Collection in reverse order

Chunking & Slicing

Break the collection into smaller collections.
const chunks = Collection.make([1, 2, 3, 4, 5, 6, 7]).chunk(3);
// Collection of Collections: [[1,2,3], [4,5,6], [7]]

chunks.each(chunk => {
  console.log(chunk.all());
});
size
number
required
Size of each chunk
return
Collection
Returns a Collection of Collection chunks
Get a slice of the collection.
const slice = collection.slice(2, 5);
start
number
required
Starting index
end
number
Ending index (exclusive)
return
Collection
Returns a new Collection with sliced items
Take the first n items.
const topFive = users.sortByDesc('points').take(5);
limit
number
required
Number of items to take
return
Collection
Returns a new Collection with first n items
Get items for a specific page.
const page2 = users.forPage(2, 20); // Page 2, 20 items per page
page
number
required
Page number (1-based)
perPage
number
required
Items per page
return
Collection
Returns a new Collection with page items

Grouping

Group items by a property.
const byStatus = users.groupBy('status');
// { active: Collection, pending: Collection, inactive: Collection }

Object.keys(byStatus).forEach(status => {
  console.log(`${status}: ${byStatus[status].count()}`);
});
key
string
required
Property name to group by
return
object
Returns an object with property values as keys and Collections as values
Key items by a property.
const byId = users.keyBy('id');
const user42 = byId[42];
key
string
required
Property name to use as key
return
object
Returns an object with property values as keys and items as values

Aggregation

Sum numeric values, optionally by a property.
const total = Collection.make([1, 2, 3, 4, 5]).sum(); // 15
const revenue = orders.sum('total');
key
string
Optional property name to sum
return
number
Returns the sum
Get the average value, optionally by a property.
const average = Collection.make([1, 2, 3, 4, 5]).avg(); // 3
const avgPrice = products.avg('price');
key
string
Optional property name to average
return
number
Returns the average
Get the maximum value, optionally by a property.
const highest = Collection.make([1, 5, 3, 2]).max(); // 5
const highestScore = users.max('score');
key
string
Optional property name
return
number|null
Returns the maximum value or null if empty
Get the minimum value, optionally by a property.
const lowest = Collection.make([3, 1, 5, 2]).min(); // 1
const lowestPrice = products.min('price');
key
string
Optional property name
return
number|null
Returns the minimum value or null if empty

Boolean Checks

Check if collection contains a value or property match.
const hasThree = Collection.make([1, 2, 3]).contains(3); // true
const hasAdmin = users.contains('role', 'admin');
key
string|any
required
Value to find, or property name if second argument provided
value
any
Optional property value to match
return
boolean
Returns true if found, false otherwise
Check if all items pass a test.
const allActive = users.every(user => user.status === 'active');
callback
function
required
Test function
return
boolean
Returns true if all items pass, false otherwise
Check if any item passes a test.
const hasAdmin = users.some(user => user.role === 'admin');
callback
function
required
Test function
return
boolean
Returns true if any item passes, false otherwise

Iteration

Iterate over items and execute a callback.
users.each(user => {
  console.log(user.name);
});

users.each((user, index) => {
  console.log(`${index}: ${user.name}`);
});
callback
function
required
Function called for each item
return
Collection
Returns the collection for chaining
Execute a callback with the collection without affecting the chain.
const result = users
  .where('status', 'active')
  .tap(collection => {
    console.log(`Found ${collection.count()} active users`);
  })
  .sortBy('name')
  .take(10);
callback
function
required
Function called with the collection
return
Collection
Returns the collection for chaining
Pass the collection through a callback and return the result.
const total = users
  .where('status', 'active')
  .pipe(collection => collection.sum('points'));
callback
function
required
Function called with the collection
return
any
Returns the callback result
Reduce the collection to a single value.
const total = Collection.make([1, 2, 3, 4]).reduce((sum, n) => sum + n, 0);

const userMap = users.reduce((map, user) => {
  map[user.id] = user;
  return map;
}, {});
callback
function
required
Reducer function
initial
any
required
Initial value
return
any
Returns the reduced value

Advanced Operations

Collapse a collection of arrays into a single flat collection.
const nested = Collection.make([[1, 2], [3, 4], [5]]);
const flat = nested.collapse();
// Collection: [1, 2, 3, 4, 5]
return
Collection
Returns a new flattened Collection
Flatten a nested collection to a specified depth.
const nested = Collection.make([1, [2, [3, [4]]]]);
const flat1 = nested.flatten(1); // [1, 2, [3, [4]]]
const flatAll = nested.flatten(); // [1, 2, 3, 4]
depth
number
default:"Infinity"
Maximum depth to flatten
return
Collection
Returns a new flattened Collection
Get items that are not in another collection.
const a = Collection.make([1, 2, 3, 4]);
const b = Collection.make([2, 4, 6]);
const diff = a.diff(b);
// Collection: [1, 3]
other
Collection|array
required
Collection or array to compare
return
Collection
Returns a new Collection with different items
Get items that are in both collections.
const a = Collection.make([1, 2, 3, 4]);
const b = Collection.make([2, 4, 6]);
const common = a.intersect(b);
// Collection: [2, 4]
other
Collection|array
required
Collection or array to intersect
return
Collection
Returns a new Collection with common items
Merge another collection or array.
const a = Collection.make([1, 2, 3]);
const b = Collection.make([4, 5, 6]);
const merged = a.merge(b);
// Collection: [1, 2, 3, 4, 5, 6]
other
Collection|array
required
Collection or array to merge
return
Collection
Returns a new merged Collection

Random & Shuffling

Get random item(s) from the collection.
const randomUser = users.random(); // Single item
const randomThree = users.random(3); // Collection of 3 items
count
number
default:"1"
Number of random items to retrieve
return
any|Collection
Returns a single item if count=1, otherwise a Collection
Randomly shuffle the collection.
const shuffled = users.shuffle();
return
Collection
Returns a new shuffled Collection

Conversion

Convert to plain array, calling toJSON() on model instances.
const users = User.all();
const array = users.toArray();
// Each user is converted via toJSON()
return
array
Returns a plain array
Convert to JSON-serializable array.
const json = JSON.stringify(users.toJSON());
return
array
Returns a JSON-serializable array
Get collection of values (for object collections).
const values = collection.values();
return
Collection
Returns a new Collection of values
Get collection of keys (for object collections).
const keys = collection.keys();
return
Collection
Returns a new Collection of keys

Complete Example

// Fetch users and chain collection methods
const result = User.all()
  .where('status', 'active')
  .where('points', '>', 100)
  .sortByDesc('points')
  .take(10)
  .map(user => ({
    id: user.id,
    name: user.name,
    points: user.points
  }));

result.each((user, index) => {
  console.log(`${index + 1}. ${user.name}: ${user.points} points`);
});

// Complex transformations
const stats = orders
  .where('status', 'completed')
  .groupBy('product_id');

Object.keys(stats).forEach(productId => {
  const productOrders = stats[productId];
  console.log(`Product ${productId}:`);
  console.log(`  Orders: ${productOrders.count()}`);
  console.log(`  Revenue: $${productOrders.sum('total')}`);
  console.log(`  Average: $${productOrders.avg('total')}`);
});

// Pagination and chunking
const page = users.forPage(2, 20);
const chunks = users.chunk(50);

chunks.each((chunk, index) => {
  console.log(`Processing batch ${index + 1}...`);
  chunk.each(user => {
    // Process each user
  });
});

// Advanced filtering and transformation
const report = Collection.make(rawData)
  .filter(item => item.date >= '2024-01-01')
  .map(item => ({
    ...item,
    category: item.type.toUpperCase(),
    value: parseFloat(item.amount)
  }))
  .groupBy('category')
  .pipe(groups => {
    const summary = {};
    Object.keys(groups).forEach(cat => {
      summary[cat] = {
        count: groups[cat].count(),
        total: groups[cat].sum('value'),
        avg: groups[cat].avg('value')
      };
    });
    return summary;
  });

Build docs developers (and LLMs) love