Moduli:table/insertIfNot

Nga Enciklopedi Puro Shqiptare
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