Pillars of Eternity Wiki
Advertisement
Pillars of Eternity Wiki
Template-info.png Module documentation

Common general purpose functions, for use in other modules so they don't have to be defined within each module.

Usage[]

Use require("Module:Common") to import this module into another module, for example:

local c = require("Module:Common")

c.someFunctionInCommonModule()
...

Functions[]

tableSelectValues[]

tableSelectValues(rootTable, key)

Loops through each of the child table "elements" within the indexed/sequential array rootTable, selecting the value of the key within that table, and adding it to a table to be returned. A value at the key should be present in each child table, and if it does not contain a value with the key, or if the child table is nil, a nil value is substituted (i.e. no checking is done).

Note that this will not work with associative (non-indexed) tables, since the output results are expected to be in numerical order.

This is a very rough equivalent of projection in C#'s LINQ (and others), where the desired values in each of the elements in an array are "projected" onto a new collection containing only those values.

local items = {
  { name = "Wooden Sword", value = 10 },
  { name = "Iron Sword", value = 250 },
  { name = "Gold Sword", value = 1500 }
}

-- Select the "value" field of each item
local values = common.tableSelectValues(items, "value")
-- Result: { 1, 250, 1500 }

TODO: Continue common documentation to same standard as above


-- Module:Common
-- Common operations that can be used across multiple modules

local libraryUtil = require('libraryUtil')

local p = {}

-- Define often-used variables and functions.
local floor = math.floor
local infinity = math.huge
local checkType = libraryUtil.checkType
local checkTypeMulti = libraryUtil.checkTypeMulti

-- Table operations

-- Loops through each of the tables within the array/table, selecting the value of the key <key> and adding it to a table to be returned
-- If the child table does not contain a value with the key, or if the child table is null, a nil value is substituted (i.e. no checking is done)
function p.tableSelectValues(rootTable, key)
	local result = { }
	
	if (rootTable ~= nil) then
		for _, childTable in ipairs(rootTable) do
			if (childTable ~= nil) then
				table.insert(result, childTable[key])
			else
				table.insert(result, nil)
			end
		end
	end
	
	return result
end
		
-- Returns true if the table/array contains a table that has a key with a specific value, otherwise returns false
function p.tableHasTableWithKeyOfValue(table, key, value)
	local result = p.tableGetTableWithKeyOfValue(table, key, value)
	return (result ~= nil)
end
	
-- Returns a table from the table/array that contains a key with a specific value, otherwise returns nil
--[[
For example calling TableGetTableWithKeyOfValue(test, "id", 1) for the following table:
test = { first = { id = 1, data = "somedata" }, second = { id = 2, data = "somemoredata" }, }
Will return: { id = 1, data="somedata" }
]]--
function p.tableGetTableWithKeyOfValue(tbl, key, value, caseInsensitive)
	
	-- Ensure that the key or table isn't nil
	if (key == nil or tbl == nil) then
		return nil
	end
	
	-- Default caseInsensitive to false
	if (caseSensitive == nil) then
		caseSensitive = false
	end
	
	-- Loop over tables in table
	for i = 1, #tbl do
		-- Check to see if the table has a value at the specified key
		if ((p.tableHasKeyWithValue(tbl[i], key, value) == true) or (caseInsensitive and p.tableHasKeyWithValueCaseInsensitive(tbl[i], key, value) == true)) then
			return tbl[i]
		end
	end
	--for _, childTable in ipairs(tbl) do
	--	if (tableHasKeyWithValue(childTable, key, value) == true) then
	--		return childTable
	--	end
	--end
	
	return nil
end
	
-- Returns true if the table has a key with a specific value (case sensitive)
function p.tableHasKeyWithValue(table, key, value)
	return (table[key] == value)
end

-- Returns true if the table has a key with a specific value (case insensitive)
function p.tableHasKeyWithValueCaseInsensitive(table, key, value)
	return (string.lower(table[key]) == string.lower(value))
end

-- Returns true if the table contains a specific value, assuming the table is indexed by integer (array-like)
function p.tableContainsValue(tbl, value)
    for _, v in ipairs(tbl) do
        if v == value then
            return true
        end
    end
    return false
end

-- Asserts if the value of the key in the input table is nil or empty, returning true if so and erroring
function p.tableValueIsNilOrEmpty(tbl, key)
	if (p.isNilOrEmpty(tbl[key]) == true) then
		error("Key \""..key.."\" in input table is nil or empty")
		return true
	else
		return false
	end
end

-- Returns true if the input table is sequentially indexed
function p.isArray(t)
	local i = 0
	for _ in pairs(t) do
		i = i + 1
		if t[i] == nil then return false end
	end
	return true
end

-- Takes a table and returns an array containing all the indexes (integer values)
-- of any numerical keys that have non-nil values, sorted in numerical order
-- Equivalent to Module:TableTools.numKeys on Wikipedia
function p.tableGetIndexes(t)
	checkType('numKeys', 1, t, 'table')
	local isPositiveInteger = p.isPositiveInteger
	local nums = {}
	for k, v in pairs(t) do
		if isPositiveInteger(k) then
			nums[#nums + 1] = k
		end
	end
	table.sort(nums)
	return nums
end

-- String operations

function p.upperCaseFirst(str)
	return (str:gsub("^%l", string.upper))
end

function p.startsWith(str, start)
   return str:sub(1, #start) == start
end

function p.endsWith(str, ending)
   return ending == "" or str:sub(-#ending) == ending
end

-- This template will add the appropriate ordinal indicator to a given number (typically integer), returning a string containing both the number and the ordinal indicator.
-- For an integer ending in 1, 2 or 3 (except for integers ending in 11, 12 or 13), the ordinal suffix will be -st, -nd and -rd, respectively.
-- If the input is not a number, no ordinal indicator will be added.
function p.stringAddOrdinal(number)
	
	local str = tostring(number)
	
	-- If the input is not a number, just return it as a string
	if (tonumber(number) == nil) then
		return str
	end
	
	if (p.endsWith(str, "1") and not p.endsWith(str, "11")) then
		return str.."st"
	elseif (p.endsWith(str, "2") and not p.endsWith(str, "12")) then
		return str.."nd"
	elseif (p.endsWith(str, "3") and not p.endsWith(str, "13")) then
		return str.."rd"
	else
		return str.."th"
	end
end

-- Number operations

-- This function returns true if the given value is a positive integer, and false if not.
function p.isPositiveInteger(v)
	return type(v) == 'number' and v >= 1 and floor(v) == v and v < infinity
end

-- This function returns true if the given number is a NaN value, and false
function p.isNan(v)
	return type(v) == 'number' and tostring(v) == '-nan'
end

-- Logical and misc operations

-- Returns true if input (string) is nil or empty
function p.isNilOrEmpty(str)
	return (str == nil or str == "")
end

function p.isNotNilOrEmpty(str)
	return not p.isNilOrEmpty(str)
end

-- Outputs the default if input is empty or nil
function p.default(input, default)
	if (input == "" or input == nil) then
		return default
	else
		return input
	end
end

-- Operates like the ternary operator in C#/JS etc
function p.ternary(condition, valueIfTrue, valueIfFalse)
	if (condition == nil or condition == false)	 then
		return valueIfFalse
	else
		return valueIfTrue
	end
end

return p
Advertisement