Module:FunList/EnumerableExtensions: Difference between revisions
From Melvor Idle
(Created page with "local Enumerable = require('Module:Enumerable') local Iterators = require('Module:Iterators') -- Helper function to check if objects are equal. local function isEqual(obj1, obj2) local type1 = type(obj1) local type2 = type(obj2) if type1 ~= type2 then return false end if type1 == "number" or type1 == "string" or type1 == "boolean" then return obj1 == obj2 elseif type1 == "table" then if #obj1 ~= #obj2 then retur...") |
(No difference)
|
Revision as of 19:38, 26 July 2024
Functions
all
-- Determines whether all elements of a sequence satisfy a condition.
---@param self Enumerable
---@param predicate fun(item: any): boolean
---@return boolean
function Enumerable:all(predicate)
any
-- Determines whether any element of a sequence exists or satisfies a condition.
---@param self Enumerable
---@param predicate fun(item: any): boolean
---@return boolean
function Enumerable:any(predicate)
append
-- Adds an item to the end of the enumerable.
---@param self Enumerable
---@param item any
function Enumerable:append(item)
prepend
-- Adds an item to the front of the enumerable.
---@param self Enumerable
---@param item any
function Enumerable:prepend(item)
contains
-- Determines whether a sequence contains a specified element.
---@param self Enumerable
---@param item any
---@return boolean
function Enumerable:contains(item)
count
-- Returns the number of elements in a sequence.
---@param self Enumerable
---@return integer
function Enumerable:count()
first
-- Returns the first element of a sequence.
---@param self Enumerable
---@param predicate? fun(item: any): boolean
---@return any
function Enumerable:first(predicate)
firstOrDefault
-- Returns the first element of a sequence, or a default value if no element is found.
---@param self Enumerable
---@param predicate? fun(item: any): boolean
---@param defaultItem? any
---@return any
function Enumerable:firstOrDefault(predicate, defaultItem)
last
-- Returns the last element of a sequence.
---@param self Enumerable
---@return any
function Enumerable:last()
lastOrDefault
-- Returns the last element of a sequence, or a default value if no element is found.
---@param self Enumerable
---@param defaultItem? any
---@return any
function Enumerable:lastOrDefault(defaultItem)
max
-- Returns the maximum value in a sequence of values.
---@param self Enumerable
---@return number
function Enumerable:max()
min
-- Returns the minimum value in a sequence of values.
---@param self Enumerable
---@return number
function Enumerable:min()
sum
-- Returns the sum value of a sequence of values.
function Enumerable:sum()
concat
-- Adds elements from one sequence to the other.
---@param self Enumerable
---@param other Enumerable
function Enumerable:concat(other)
difference
-- Gets the difference between two sequences
---@param self Enumerable
---@param other Enumerable
function Enumerable:difference(other)
differenceBy
-- Gets the difference between two sequences based on a key
---@param self Enumerable
---@param keySelector? fun(value: any, index: any): any
function Enumerable:differenceBy(other, keySelector)
flatMap
-- Maps items from one sequence to another.
---@param self Enumerable
---@param selector fun(value: any, index: integer): any
function Enumerable:flatMap(selector)
groupBy
--Groups the elements of a sequence.
---@param self Enumerable
---@param keySelector fun(param: any): any
---@param elementSelector? fun(param: any): any
function Enumerable:groupBy(keySelector, elementSelector)
groupByResult
--Groups the elements of a sequence according to a specified key selector function and creates a result value from each group and its key. The elements of each group are projected by using a specified function.
---@param self Enumerable
---@param keySelector fun(param: any): any
---@param elementSelector? fun(param: any): any
---@param resultSelector fun(key: any, grouping: Grouping): any
function Enumerable:groupByResult(keySelector, elementSelector, resultSelector)
intersect
--Produces the set intersection of two sequences.
---@param self Enumerable
---@param other Enumerable
function Enumerable:intersect(other)
intersectBy
--Produces the set intersection of two sequences according to a specified key selector function.
---@param self Enumerable
---@param other Enumerable
---@param keySelector? fun(value: any, index: any): any
function Enumerable:intersectBy(other, keySelector)
map
--Projects each element of a sequence into a new form.
---@param self Enumerable
---@param selector fun(value: any, index: any): any
function Enumerable:map(selector)
sort
--Sorts a sequence.
---@param self Enumerable
---@return SortableIterator
function Enumerable:sort()
sortDescending
--Sorts a sequence in descending order.
---@param self Enumerable
---@return SortableIterator
function Enumerable:sortDescending()
sortBy
--Sorts a sequence based on a specified key selector function.
---@param self Enumerable
---@return SortableIterator
function Enumerable:sortBy(keySelector)
sortByDescending
--Sorts a sequence based on a specified key selector function in descending order.
---@param self Enumerable
---@return SortableIterator
function Enumerable:sortByDescending(keySelector)
thenSortBy
--Sorts a sorted sequence further based on a specified key selector function.
---@param self SortableIterator
---@return SortableIterator
function Enumerable:thenSortBy(keySelector)
thenSortByDescending
--Sorts a sorted sequence further based on a specified key selector function in descending order.
---@param self SortableIterator
---@return SortableIterator
function Enumerable:thenSortByDescending(keySelector)
union
--Produces the set union of two sequences according to a specified key selector function.
---@param self Enumerable
---@param other any
function Enumerable:union(other)
unionBy
--Produces the set union of two sequences according to a specified key selector function.
---@param self Enumerable
---@param other any
---@param keySelector? fun(value: any, index: any): any
function Enumerable:unionBy(other, keySelector)
unique
--Returns unique (distinct) elements from a sequence according to a specified key selector function.
---@param self Enumerable
function Enumerable:unique()
uniqueBy
--Returns unique (distinct) elements from a sequence according to a specified key selector function.
---@param self Enumerable
---@param keySelector? fun(value: any, index: any): any
function Enumerable:uniqueBy(keySelector)
where
--Filters a sequence of values based on a predicate.
---@param self Enumerable
---@param predicate fun(value: any, index: any): boolean
function Enumerable:where(predicate)
zip
--Projects each element of a sequence to an Enumerable and flattens the resulting sequences into one sequence.
---@param self Enumerable
---@param other any
function Enumerable:zip(other)
zipBy
--Projects each element of a sequence to an Enumerable and flattens the resulting sequences into one sequence.
---@param self Enumerable
---@param other any
---@param resultSelector? fun(left: any, right: any): any
function Enumerable:zipBy(other, resultSelector)
toDictionary
---@param self Enumerable
---@param keySelector fun(item: any, index: any): any
---@param valueSelector fun(item: any, index: any): any
---@return table
function Enumerable:toDictionary(keySelector, valueSelector)
toTable
---@param self Enumerable
---@return table
function Enumerable:toTable()
toHashSet
---@param self Enumerable
---@return table
function Enumerable:toHashSet()
local Enumerable = require('Module:Enumerable')
local Iterators = require('Module:Iterators')
-- Helper function to check if objects are equal.
local function isEqual(obj1, obj2)
local type1 = type(obj1)
local type2 = type(obj2)
if type1 ~= type2 then
return false
end
if type1 == "number" or type1 == "string" or type1 == "boolean" then
return obj1 == obj2
elseif type1 == "table" then
if #obj1 ~= #obj2 then
return false
end
for k, v in pairs(obj1) do
if not isEqual(v, obj2[k]) then
return false
end
end
return true
else
return obj1 == obj2
end
end
-- Determines whether all elements of a sequence satisfy a condition.
---@param self Enumerable
---@param predicate fun(item: any): boolean
---@return boolean
function Enumerable:all(predicate)
assert(predicate)
local enum = self:getEnumerator()
while enum:moveNext() == true do
if predicate(enum.current) == false then
return false
end
end
return true
end
-- Determines whether any element of a sequence exists or satisfies a condition.
---@param self Enumerable
---@param predicate fun(item: any): boolean
---@return boolean
function Enumerable:any(predicate)
assert(predicate)
local enum = self:getEnumerator()
if predicate then
while enum:moveNext() == true do
if predicate(enum.current) == true then
return true
end
end
else
while enum:moveNext() == true do
return true
end
end
return false
end
-- Adds an item to the end of the enumerable
---@param self Enumerable
---@param item any
function Enumerable:append(item)
return Iterators.AppendIterator.new(self, item, nil, true)
end
-- Adds an item to the front of the enumerable
---@param self Enumerable
---@param item any
function Enumerable:prepend(item)
return Iterators.AppendIterator.new(self, item, nil, false)
end
-- Determines whether a sequence contains a specified element.
---@param self Enumerable
---@param item any
---@return boolean
function Enumerable:contains(item)
assert(item)
local enum = self:getEnumerator()
while enum:moveNext() == true do
if isEqual(enum.current, item) == true then
return true
end
end
return false
end
-- Returns the number of elements in a sequence.
---@param self Enumerable
---@return integer
function Enumerable:count()
if self.getCount ~= nil then
return self:getCount()
end
local count = 0
local enum = self:getEnumerator()
while enum:moveNext() do
count = count + 1
end
return count
end
-- Returns the first element of a sequence.
---@param self Enumerable
---@param predicate? fun(item: any): boolean
---@return any
function Enumerable:first(predicate)
local result = Enumerable.firstOrDefault(self, predicate, nil)
if result ~= nil then
return result
end
error('No items in sequence.')
end
-- Returns the first element of a sequence, or a default value if no element is found.
---@param self Enumerable
---@param predicate? fun(item: any): boolean
---@param defaultItem? any
---@return any
function Enumerable:firstOrDefault(predicate, defaultItem)
assert(predicate)
local enum = self:getEnumerator()
if predicate then
while enum:moveNext() do
if predicate(enum.current) == true then
return enum.current
end
end
else
while enum:moveNext() do
return enum.current
end
end
return defaultItem
end
-- Returns the last element of a sequence.
---@param self Enumerable
---@return any
function Enumerable:last()
local result = Enumerable.lastOrDefault(self, nil)
if result ~= nil then
return result
end
error('Sequence contains no items.')
end
-- Returns the last element of a sequence, or a default value if no element is found.
---@param self Enumerable
---@param defaultItem? any
---@return any
function Enumerable:lastOrDefault(defaultItem)
local enum = self:getEnumerator()
local last = nil
if self.getLast ~= nil then
last = self:getLast()
else
-- Run enumerator to the end.
while enum:moveNext() == true do end
last = enum.current
end
return last
end
-- Returns the maximum value in a sequence of values.
---@param self Enumerable
---@return number
function Enumerable:max()
local h = Enumerable.first(self)
local enum = self:getEnumerator()
while enum:moveNext() do
local num = tonumber(enum.current)
if num == nil then
error('Value is NaN')
end
if num > h then h = num end
end
return h
end
-- Returns the minimum value in a sequence of values.
---@param self Enumerable
---@return number
function Enumerable:min()
local l = Enumerable.first(self)
local enum = self:getEnumerator()
while enum:moveNext() do
local num = tonumber(enum.current)
if num == nil then
error('Value is NaN')
end
if num < l then l = num end
end
return l
end
function Enumerable:sum()
local total = 0
local enum = self:getEnumerator()
while enum:moveNext() do
local num = tonumber(enum.current)
if num == nil then
error('Value is NaN')
end
total = total + num
end
return total
end
-- Adds elements from one sequence to the other.
---@param self Enumerable
---@param other Enumerable
function Enumerable:concat(other)
return Iterators.ConcatIterator.new(self, other)
end
-- Gets the difference between two sequences
---@param self Enumerable
---@param other Enumerable
function Enumerable:difference(other)
return Iterators.DifferenceIterator.new(self, other)
end
-- Gets the difference between two sequences based on a key
---@param self Enumerable
---@param keySelector? fun(value: any, index: any): any
function Enumerable:differenceBy(other, keySelector)
return Iterators.DifferenceIterator.new(self, other, keySelector)
end
-- Maps items from one sequence to another.
---@param self Enumerable
---@param selector fun(value: any, index: integer): any
function Enumerable:flatMap(selector)
return Iterators.FlatMapIterator.new(self, selector)
end
---@param self Enumerable
---@param keySelector fun(param: any): any
---@param elementSelector? fun(param: any): any
function Enumerable:groupBy(keySelector, elementSelector)
return Iterators.GroupByIterator.new(self, keySelector, elementSelector)
end
---@param self Enumerable
---@param keySelector fun(param: any): any
---@param elementSelector? fun(param: any): any
---@param resultSelector fun(key: any, grouping: Grouping): any
function Enumerable:groupByResult(keySelector, elementSelector, resultSelector)
return Iterators.GroupByResultIterator.new(self, keySelector, elementSelector, resultSelector)
end
---@param self Enumerable
---@param other Enumerable
function Enumerable:intersect(other)
return Iterators.IntersectIterator.new(self, other)
end
---@param self Enumerable
---@param other Enumerable
---@param keySelector? fun(value: any, index: any): any
function Enumerable:intersectBy(other, keySelector)
return Iterators.IntersectIterator.new(self, other, keySelector)
end
---@param self Enumerable
---@param selector fun(value: any, index: any): any
function Enumerable:map(selector)
return Iterators.MapIterator.new(self, selector)
end
---@param self Enumerable
---@return SortableIterator
function Enumerable:sort()
return Iterators.SortableIterator.new(self, function(x) return x end, false)
end
---@param self Enumerable
---@return SortableIterator
function Enumerable:sortDescending()
return Iterators.SortableIterator.new(self, function(x) return x end, true)
end
---@param self Enumerable
---@return SortableIterator
function Enumerable:sortBy(keySelector)
return Iterators.SortableIterator.new(self, keySelector, false)
end
---@param self Enumerable
---@return SortableIterator
function Enumerable:sortByDescending(keySelector)
return Iterators.SortableIterator.new(self, keySelector, true)
end
---@param self SortableIterator
---@return SortableIterator
function Enumerable:thenSortBy(keySelector)
assert(self.createSortableIterator, 'Previous operation must be a Sort or SortBy')
return self:createSortableIterator(keySelector, false)
end
---@param self SortableIterator
---@return SortableIterator
function Enumerable:thenSortByDescending(keySelector)
assert(self.createSortableIterator, 'Previous operation must be a Sort or SortBy')
return self:createSortableIterator(keySelector, true)
end
---@param self Enumerable
---@param other any
function Enumerable:union(other)
return Iterators.UnionIterator.new(self, other)
end
---@param self Enumerable
---@param other any
---@param keySelector? fun(value: any, index: any): any
function Enumerable:unionBy(other, keySelector)
return Iterators.UnionIterator.new(self, other, keySelector)
end
---@param self Enumerable
function Enumerable:unique()
return Iterators.UniqueIterator.new(self)
end
---@param self Enumerable
---@param keySelector? fun(value: any, index: any): any
function Enumerable:uniqueBy(keySelector)
return Iterators.UniqueIterator.new(self, keySelector)
end
---@param self Enumerable
---@param predicate fun(value: any, index: any): boolean
function Enumerable:where(predicate)
return Iterators.WhereIterator.new(self, predicate)
end
---@param self Enumerable
---@param other any
function Enumerable:zip(other)
return Iterators.ZipIterator.new(self, other)
end
---@param self Enumerable
---@param other any
---@param resultSelector? fun(left: any, right: any): any
function Enumerable:zipBy(other, resultSelector)
return Iterators.ZipIterator.new(self, other, resultSelector)
end
---@param self Enumerable
---@param keySelector fun(item: any, index: any): any
---@param valueSelector fun(item: any, index: any): any
---@return table
function Enumerable:toDictionary(keySelector, valueSelector)
assert(keySelector)
assert(valueSelector)
local tbl = {}
local enum = self:getEnumerator()
while enum:moveNext() == true do
local index = enum.index
local current = enum.current
local key = keySelector(current, index)
local value = valueSelector(current, index)
tbl[key] = value
end
return tbl
end
---@param self Enumerable
---@return table
function Enumerable:toTable()
if self.getTable ~= nil then
return self:getTable()
end
local tbl = {}
local enum = self:getEnumerator()
while enum:moveNext() do
table.insert(tbl, enum.current)
end
return tbl
end
---@param self Enumerable
---@param keySelector fun(item: any, index: any): any
---@return table
function Enumerable:toHashSet(keySelector)
local set = {}
local enum = self:getEnumerator()
while enum:moveNext() == true do
local key = keySelector(enum.current, enum.index)
set[key] = true
end
return set
end