lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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.