Moduli:table/insertIfNot
Jump to navigation
Jump to search
Udhëzuesi për këtë modul mund të krijohet te Moduli:table/insertIfNot/doc.
local table_find_module = "Module:table/find"
local insert = table.insert
local type = type
local function table_find(...)
table_find = require(table_find_module)
return table_find(...)
end
--[==[
Given a `list` and a `new_item` to be inserted, append the value to the end of the list if not already present (or insert at an arbitrary position, if `options.pos` is given; see below). Comparison is by value, using {deepEquals}.
`options` is an optional table of additional options to control the behavior of the operation. The following options are recognized:
* `pos`: Position at which insertion happens (i.e. before the existing item at position `pos`).
* `comparison`: Function of two arguments to compare whether `item` is equal to an existing item in `list`. If unspecified, items are considered equal if either the standard equality operator {==} or {deepEquals} return {true}. As a special case, if the string value {"=="} is specified, then the standard equality operator alone will be used.
* `key`: Function of one argument to return a comparison key, which will be used with the comparison function. The key function is applied to both `item` and the existing item in `list` to compare against, and the comparison is done against the results. This is useful when inserting a complex structure into an existing list while avoiding duplicates.
* `combine`: Function of three arguments (the existing item, the new item and the position, respectively) to combine an existing item with `new_item`, when `new_item` is found in `list`. If unspecified, the existing item is left alone.
Returns {false} if an entry is already found, or {true} if inserted. By default, {false} indicates that no change was made to the input table, but if the `combine` is used, {false} indicates that the pre-existing entry was modified.
For compatibility, `pos` can be specified directly as the third argument in place of `options`, but this is not recommended for new code.
NOTE: This function is O(N) in the size of the existing list. If you use this function in a loop to insert several items, you will get O(M*(M+N)) behavior, effectively O((M+N)^2). Thus it is not recommended to use this unless you are sure the total number of items will be small. (An alternative for large lists is to insert all the items without checking for duplicates, and use {removeDuplicates()} at the end.)]==]
return function(list, new_item, options)
local pos
if options then
if type(options) == "number" then
pos, options = options, nil
else
pos = options.pos
end
end
local i = table_find(list, new_item, options)
if not i then
if pos == nil then
insert(list, new_item)
else
insert(list, pos, new_item)
end
return true
elseif options ~= nil then
local combine_func = options.combine
if combine_func ~= nil then
local newval = combine_func(list[i], new_item, i)
if newval ~= nil then
list[i] = newval
end
end
end
return false
end