lua-users home
lua-l archive

Re: Memoizing Functions - yet another attempt

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


On Dec 15, 2013, at 2:34 PM, Sir Pogsalot <sir.pogsalot@gmail.com> wrote:
> On the other hand…
Quagmire or not, here is a little recursive table signer for entertainment purpose.
Usage example:
local foo = Memoize( function( aTable) return aTable, table.unpack( aTable ) end, TableSigner )
local aTable = { 1, 2, 3, 4, 5, 6 }
print( 'foo', 1, foo( { 1, 2, 3 } ) )
print( 'foo', 2, foo( { 1, 2, 3 } ) )
print( 'foo', 3, foo( { a = 1, b = 2, c = 3 } ) )
print( 'foo', 4, foo( { a = 1, b = 2, c = 3 } ) )
print( 'foo', 5, foo( { {}, {}, {} } ) )
print( 'foo', 6, foo( { {}, {}, {} } ) )
print( 'foo', 7, foo( aTable ) )
aTable[ #aTable + 1 ] = aTable
aTable[ #aTable + 1 ] = aTable
aTable[ #aTable + 1 ] = aTable
aTable[ #aTable + 1 ] = true
aTable[ aTable ] = aTable
print( 'foo', 8, foo( aTable ) )
print( 'foo', 9, foo( aTable ) )
Whole hog:
local function Key( aSigner, ... )
 local aBuffer = {}
 for anIndex = 1, select( '#', ... ) do
 aBuffer[ #aBuffer + 1 ] = aSigner( select( anIndex, ... ) )
 end
 return table.concat( aBuffer )
end
local function Signer( aValue )
 return ( tostring( aValue or '' ) or '' ) .. type( aValue ):sub( 1, 2 )
end
local function Memoize( aFunction, aSigner )
 local aCache = {}
 local aSigner = aSigner or Signer
 return function( ... )
 local aKey = Key( aSigner, ... )
 local aValue = aCache[ aKey ] or table.pack( aFunction( ... ) )
 aCache[ aKey ] = aValue
 return table.unpack( aValue, 1, aValue.n )
 end
end
local function TableSigner( aValue, aSet, aCounter )
 local aSet = aSet or {}
 local aCounter = aCounter or 0
 if type( aValue ) == 'table' and not aSet[ aValue ] then
 local aBuffer = {}
 aCounter = aCounter + 1
 aSet[ aValue ] = ( '%dta' ):format( aCounter )
 for aTableKey, aTableValue in pairs( aValue ) do
 aBuffer[ #aBuffer + 1 ] = TableSigner( aTableKey, aSet, aCounter ) .. TableSigner( aTableValue, aSet, aCounter )
 end
 table.sort( aBuffer )
 aBuffer[ #aBuffer + 1 ] = 'ta'
 aSet[ aValue ] = table.concat( aBuffer )
 end
 return aSet[ aValue ] or Signer( aValue )
end

AltStyle によって変換されたページ (->オリジナル) /