[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: pairs and ipairs
- From: Francisco Olarte <folarte@...>
- Date: Mon, 23 Oct 2023 10:00:31 +0200
On Sun, 22 Oct 2023 at 22:15, Petite Abeille <petite.abeille@gmail.com> wrote:
> local function kpairs( aTable )
> local aLength = 0 -- #aTable ~= ipairs( aTable )
>
> for anIndex, _ in ipairs( aTable ) do
> aLength = anIndex
> end
>
> return coroutine.wrap
> (
> function()
> for aKey, aValue in pairs( aTable ) do
> if not ( math.type( aKey ) == 'integer' and aKey >= 1 and aKey <= aLength ) then coroutine.yield( aKey, aValue ) end
> end
> end
> )
> end
Given the language gives you mechanism to build loops, generators (
this coroutine looks like a generator in disguise ) are a bit overkill
for just an iterator:
>>>>
local function kpairs( aTable )
local aNext = 1
while aTable[aNext] ~= nil do
aNext = aNext+1
end
local function kNext(t,k)
local v;
k,v = next(t,k)
-- Extra advantage of un-negating the condition ( IMO )
while math.type(k)=="integer" and k>=1 and k<aNext do
k,v = next(t,k)
end
return k,v
end
return kNext, aTable, nil
end
<<<
The closure could be zapped by using { aTable, aNext } as the state,
but hey, this is not C.
Given the language does the boring stuff of looping, I in general
prefer to do these things by customizing the next/state stuff. This
kind of construct appear so much that I have things like this sitting
around:
>>>>
local function pred_next(pred, t,lastk)
local k,v = next(t,lastk)
while k ~= nil and not pred(t,k,v) do
k,v = next(t,k)
end
return k,v
end
local function make_next(pred)
return function(...)
return pred_next(pred,...)
end
end
local function pkpairs(aTable)
local aNext = 1
while aTable[aNext] ~= nil do
aNext = aNext+1
end
local function not_in_list(_t,k,_v)
return not (math.type(k)=="integer" and k>=1 and k<aNext)
end
return make_next(not_in_list),aTable,nil
end
<<<<
Francisco Olarte.