Expand the reduce function to both fold and reduce (#6337)
This commit is contained in:
parent
e81cef3a08
commit
bff219d41f
4 changed files with 51 additions and 8 deletions
|
@ -14,4 +14,4 @@ global=false
|
|||
unused=false
|
||||
-- excluded files due to using lua 5.4 syntax that currently gets flagged as a syntax error
|
||||
-- clear out once a newer Ubuntu LTS base is used for our docker images, which would then also have a newer luacheck available
|
||||
exclude_files={"data/lua/core/wml.lua","data/lua/wml-flow.lua","data/lua/wml/find_path.lua","data/lua/wml/harm_unit.lua","data/lua/wml/modify_unit.lua","data/lua/wml/random_placement.lua"}
|
||||
exclude_files={"data/lua/core/wml.lua","data/lua/wml-flow.lua","data/lua/wml/find_path.lua","data/lua/wml/harm_unit.lua","data/lua/wml/modify_unit.lua","data/lua/wml/random_placement.lua","data/lua/functional.lua"}
|
||||
|
|
|
@ -126,15 +126,28 @@ local known_operators = {
|
|||
['or'] = function(a, b) return a or b end,
|
||||
}
|
||||
|
||||
function functional.reduce(input, operator, identity)
|
||||
if type(operator) == 'string' then
|
||||
operator = known_operators[operator]
|
||||
--- Reduce the elements of array t into a single value. operator is called as
|
||||
--- 'operator(accumulator, element)' for every element in t. If a 3rd argument
|
||||
--- is provided, which may be nil, it will be used as the accumulator when
|
||||
--- calling operator on the first element. If there is no 3rd argument, the
|
||||
--- first operator call will be on the first two elements. If there is no 3rd
|
||||
--- argument and the array is empty, return nil. operator may be a function or a
|
||||
--- binary Lua operator as a string.
|
||||
function functional.reduce(t, operator, ...)
|
||||
local f <const> = known_operators[operator] or operator
|
||||
|
||||
local function loop(init, i)
|
||||
local value <const> = t[i]
|
||||
if value == nil then
|
||||
return init
|
||||
end
|
||||
return loop(f(init, value), i + 1)
|
||||
end
|
||||
local result = identity or 0
|
||||
for _, v in ipairs(input) do
|
||||
result = operator(result, v)
|
||||
|
||||
if select('#', ...) == 0 then
|
||||
return loop(t[1], 2)
|
||||
end
|
||||
return result
|
||||
return loop(select(1, ...), 1)
|
||||
end
|
||||
|
||||
function functional.take_while(input, condition)
|
||||
|
|
29
data/test/scenarios/lua_functional.cfg
Normal file
29
data/test/scenarios/lua_functional.cfg
Normal file
|
@ -0,0 +1,29 @@
|
|||
#textdomain wesnoth-test
|
||||
|
||||
# Tests for the functional.lua library
|
||||
{GENERIC_UNIT_TEST "lua_functional" (
|
||||
[event]
|
||||
name = start
|
||||
[lua]
|
||||
code = <<
|
||||
local fp <const> = wesnoth.require'lua/functional'
|
||||
|
||||
unit_test.assert_equal(
|
||||
fp.reduce({}, function() end),
|
||||
nil,
|
||||
"reduce with empty array and no init doesn't return nil.")
|
||||
|
||||
unit_test.assert(
|
||||
not fp.reduce({false, false}, 'or', false),
|
||||
"reduce with false elements and 'or' operator returns a truthy value.")
|
||||
|
||||
unit_test.assert_equal(
|
||||
fp.reduce({4, 5, 2}, '+', 0),
|
||||
11,
|
||||
"reduce does not calculate a sum correctly.")
|
||||
|
||||
unit_test.succeed()
|
||||
>>
|
||||
[/lua]
|
||||
[/event]
|
||||
)}
|
|
@ -351,6 +351,7 @@
|
|||
9 unknown_scenario_1_0
|
||||
|
||||
# Lua API tests
|
||||
0 lua_functional
|
||||
0 lua_map_find
|
||||
0 mapgen_filter_range
|
||||
0 mapgen_filter_terrain
|
||||
|
|
Loading…
Add table
Reference in a new issue