batteries/sequence.lua

99 lines
2.1 KiB
Lua

--[[
sequence - functional + oo wrapper for ordered tables
mainly beneficial when used for method chaining
to save on typing and data plumbing
]]
local path = (...):gsub("sequence", "")
local class = require(path .. "class")
local table = require(path .. "tablex") --shadow global table module
local functional = require(path .. "functional")
local stable_sort = require(path .. "sort").stable_sort
local sequence = class(table) --proxy missing table fns to tablex api
--upgrade a table into a sequence, or create a new sequence
function sequence:new(t)
return self:init(t or {})
end
--sorting default to stable
sequence.sort = stable_sort
--patch various interfaces in a type-preserving way, for method chaining
--import copying tablex
function sequence:keys()
return sequence(table.keys(self))
end
function sequence:values()
return sequence(table.values(self))
end
function sequence:dedupe()
return sequence(table.dedupe(self))
end
function sequence:collapse()
return sequence(table.collapse(self))
end
sequence.flatten = sequence.collapse
function sequence:append(...)
return sequence(table.append(self, ...))
end
function sequence:overlay(...)
return sequence(table.overlay(self, ...))
end
function sequence:copy(...)
return sequence(table.copy(self, ...))
end
--import functional interface in method form
--(common case where something returns another sequence for chaining)
for _, v in ipairs({
"map",
"map_inplace",
"filter",
"filter_inplace",
"remove_if",
"zip",
"stitch",
"cycle",
}) do
local functional_f = functional[v]
sequence[v] = function(self, ...)
return sequence(functional_f(self, ...))
end
end
--aliases
for _, v in ipairs({
{"remap", "map_inplace"},
{"map_stitch", "stitch"},
{"map_cycle", "cycle"},
}) do
sequence[v[1]] = sequence[v[2]]
end
--(less common cases where we don't want to construct a new sequence or have more than one return value)
function sequence:foreach(f)
return functional.foreach(self, f)
end
function sequence:reduce(seed, f)
return functional.reduce(self, seed, f)
end
function sequence:partition(f)
local a, b = functional.partition(self, f)
return sequence(a), sequence(b)
end
return sequence