Skip to content

Collection

Source: shiva-fw/libs/collection/init.lua

Laravel-inspired collection class with fluent chaining, dot-notation key access, and conditional pipelines.

Availability

Collection and the collect() global helper are available in every shiva module (loaded by sh_init.lua). No import required.

Creating a Collection

Collection.new(items?)

lua
local c = Collection.new({ 1, 2, 3 })

collect(items?)

Shorthand global helper.

lua
local c = collect({ 'a', 'b', 'c' })

Retrieval

:all()

Return all items as a plain Lua table.

lua
c:all()  -- { 1, 2, 3 }

:count()

Number of items.

lua
c:count()  -- 3

:first(fn?)

First item, optionally matching a predicate.

lua
c:first()                            -- 1
c:first(function(x) return x > 1 end)  -- 2

:last(fn?)

Last item, optionally matching a predicate.

lua
c:last()

:get(index)

Item at a specific 1-based index.

lua
c:get(2)  -- 2

:find(key, value)

Find the first item where item[key] == value (dot notation supported).

lua
local player = players:find('id', 42)

:contains(key_or_fn, value?)

Returns true if any item matches. Pass a key+value or a predicate function.

lua
c:contains(function(x) return x > 5 end)
players:contains('id', 42)

:isEmpty() / :isNotEmpty()

lua
if c:isEmpty() then ... end

Filtering

:filter(fn)

Keep items that match the predicate.

lua
c:filter(function(x) return x % 2 == 0 end)

:reject(fn)

Keep items that do not match the predicate.

lua
c:reject(function(x) return x < 0 end)

:where(key, op_or_value, value?)

Filter by key comparison. Operator is optional (defaults to ==).

lua
players:where('job', 'police')
players:where('level', '>', 10)

:whereIn(key, values)

Keep items whose key is in the values array.

lua
players:whereIn('job', { 'police', 'ems' })

:whereNotNil(key)

Keep items where item[key] is not nil.

lua
items:whereNotNil('metadata')

:whereBetween(key, min, max)

Keep items where item[key] is between min and max (inclusive).

lua
items:whereBetween('price', 100, 500)

Transformation

:map(fn)

Transform each item.

lua
c:map(function(x) return x * 2 end)

:flatMap(fn)

Map each item to an array, then flatten one level.

lua
orders:flatMap(function(o) return o.items end)

:pluck(key)

Extract a single field from each item.

lua
players:pluck('name')  -- Collection of names

:unique(key?)

Remove duplicate items, optionally by key.

lua
c:unique()
players:unique('job')

:keyBy(key)

Re-index the collection by a key field. Returns a plain table.

lua
local byId = players:keyBy('id')  -- table<id, player>

:groupBy(key_or_fn)

Group items by key or function. Returns a table of Collections.

lua
local byJob = players:groupBy('job')

:chunk(size)

Split into a Collection of Collections of the given size.

lua
c:chunk(3)

Iteration

:each(fn)

Iterate over each item (side effects only, not chainable).

lua
c:each(function(item, index) print(index, item) end)

Aggregation

:sum(key?)

Sum all values or a numeric key.

lua
c:sum()
orders:sum('total')

:min(key?) / :max(key?)

lua
c:min()
items:max('price')

:avg(key?)

Average value.

lua
orders:avg('total')

:reduce(fn, initial?)

Reduce to a single value.

lua
c:reduce(function(carry, item) return carry + item end, 0)

Sorting

:sortBy(key_or_fn, direction?)

Sort by key or function. direction is 'asc' (default) or 'desc'.

lua
players:sortBy('name')
players:sortBy('level', 'desc')

Conditional Pipelines

:when(condition, fn)

Run fn(collection) only when condition is truthy.

lua
c:when(isAdmin, function(col) return col:filter(...) end)

:unless(condition, fn)

Run fn(collection) only when condition is falsy.

lua
c:unless(isEmpty, function(col) return col:sortBy('name') end)

Released under the MIT License.