--[[ Provides an implementation of functional programming primitives. ]] local Functional = {} --[[ Create a copy of a list with only values for which `callback` returns true ]] function Functional.Filter(list, callback) local new = {} for key = 1, #list do local value = list[key] if callback(value, key) then table.insert(new, value) end end return new end --[[ Create a copy of a list where each value is transformed by `callback` ]] function Functional.Map(list, callback) local new = {} for key = 1, #list do new[key] = callback(list[key], key) end return new end --[[ Identical to Map, except that the result will be reversed. ]] function Functional.MapReverse(list, callback) local new = {} for key = #list, 1, -1 do new[key] = callback(list[key], key) end return new end --[[ Create a copy of a list doing a combination filter and map. If callback returns nil for any item, it is considered filtered from the list. Any other value is considered the result of the 'map' operation. ]] function Functional.FilterMap(list, callback) local new = {} for key = 1, #list do local value = list[key] local result = callback(value, key) if result ~= nil then table.insert(new, result) end end return new end --[[ Performs a left-fold of the list with the given initial value and callback. ]] function Functional.Fold(list, initial, callback) local accum = initial for key = 1, #list do accum = callback(accum, list[key], key) end return accum end --[[ Performs a fold over the entries in the given dictionary. ]] function Functional.FoldDictionary(dictionary, initial, callback) local accum = initial for key, value in pairs(dictionary) do accum = callback(accum, key, value) end return accum end --[[ Returns a list that contains at most `count` values from the given list. ]] function Functional.Take(list, count, startingIndex) startingIndex = startingIndex or 1 local maxIndex = count + (startingIndex - 1) if maxIndex > #list then maxIndex = #list end local new = {} for i = startingIndex, maxIndex do local value = list[i] local newIndex = i - (startingIndex - 1) new[newIndex] = value end return new end --[[ If the list contains the sought-after element, return its index, or nil otherwise. ]] function Functional.Find(list, value) for index, element in ipairs(list) do if element == value then return index end end return nil end return Functional