You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.2 KiB

-- Neuron is a World of Warcraft® user interface addon.
-- Copyright (c) 2017-2021 Britt W. Yazel
-- Copyright (c) 2006-2014 Connor H. Chenoweth
-- This code is licensed under the MIT license (see LICENSE for details)
local _, addonTable = ...
addonTable.utilities = addonTable.utilities or {}
local Array; Array = {
---create an array
---number -> (number -> A ) -> A[]
---@generic A
---@param n number @length of array
---@param fn fun(i:number):A @function takes index and returns array element
---@return A[] @an array of length n
initialize = function (n, fn)
local array = {}
for i=1,n do
array[i] = fn(i)
end
return array
end,
---returns a new array, different from the components
---@param ... any[]
---@return any[]
concatenate = function (...)
local result = {}
for _,array in ipairs({...}) do
for _,element in ipairs(array) do
table.insert(result, element)
end
end
return result
end,
---remove items from an array if a test function returns falsey
---@generic A
---@param fn fun(a:`A`):boolean @test function
---@param array A[] @input array
---@return A[] @filtered array
filter = function (fn, array)
local newArray = {}
for _,v in ipairs(array) do
if fn(v) then
table.insert(newArray, v)
end
end
return newArray
end,
---remove items from an array if a test function returns falsey
---@generic A
---@param fn fun(a:`A`):boolean @test function
---@param array A[] @input array
---@return number|nil, A|nil @position of element
find = function (fn, array)
for i,v in ipairs(array) do
if fn(v) then
return i, v
end
end
return nil
end,
---aka reduce
---@generic A, B
---@param fn fun(a: `A`, b: `B`):A
---@param initial A @initial value
---@param array B[] @input array
---@return A @folded value
foldl = function (fn, initial, array)
for _,v in ipairs(array) do
initial = fn(initial, v)
end
return initial
end,
---converts an iterator to an array
---this exists because iterators are thruples, but lua has no real support
---for tuples outside of return/parameter values. this results in way to much
---boilerplate when packing/unpacking iterators<->arrays in order to
---pass them around as first class objects. not to mention that iterators
---themselves can return tuples, besides _being_ tuples
---@generic I, C, D
---@param iter fun(invariant: I, control: C):D|...
---@param invariant I
---@param control C
---@return D[]|...[]
fromIterator = function(iter, invariant, control)
local result = {}
local index = 1
repeat
local nextValue = {iter(invariant, control)}
-- if the iterator returned a single value, then insert that
-- if the iterator returned a tuple, then insert that tuple as an array
if #nextValue < 2 then
table.insert(result, index, nextValue[1])
else
table.insert(result, index, nextValue)
end
control = unpack(nextValue)
index = index + 1
until control == nil
return result
end,
---map from one array to another
---(A->B) -> A[] -> B[]
---@generic A
---@generic B
---@param fn fun(a:A):B
---@param array A[] @source array
---@return B[] @remapped array
map = function (fn, array)
return Array.initialize(#array, function (i) return fn(array[i]) end)
end,
}
addonTable.utilities.Array = Array