lua-users home
lua-l archive

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

spir wrote:
> David Given <> wrote:
>> - - bidirectional --- where the array part and the keyed part contain the
>> some data, but opposite ways around. So t["one"] == 1 and t[1] == "one".
> Waow, clever!

I use this technique often. I call it a xref table. The code below sets
__newindex to automatically add the key to the array part if it doesn't
already exist. I rarely use the del() function.

One of the things that I like about this approach is that I can sort the
array part in different ways and print the values in the sorted order.
See the example below.

-- xref.lua:

-- Provides a table that contains:
--   o A list of keys in the array part.
--   o For each key, xref[key] = value.

local ipairs       = ipairs
local pairs        = pairs
local rawset       = rawset
local setmetatable = setmetatable
local table_remove = table.remove
local type         = type


local xref = {}

function add(t, k, v)
   -- If we had __usedindex then we could use this function when
   -- v is nil, too. But if the key already exists, then
   -- __newindex is not called. Hence xref.del().

   if t[k] == nil then
      -- If the key is not in the xref, add it.
      rawset(t, #t+1, k)

   rawset(t, k, v)
end   -- add()

function del(t, k)
   for i, key in ipairs(t) do
      if key == k then
         table_remove(t, i)

   rawset(t, k, nil)
end   -- del()

local mt = {
   __newindex = add

function new(t)
   t = t or {}

   if type(t) ~= 'table' then
      error('table expected, got ' .. type(t))

   if #t > 0 then
      error('initialization table should not contain an array part')

   for k, v in pairs(t) do
      t[#t+1] = k

   return setmetatable(t, mt)

-- End of xref.lua.

-- Test run:

t = { name='Fred', last='Flintstone' }
t =

print("After initialization:")
for i, k in ipairs(t) do
   print(i, k, t[k])

t.boss = 'Slate'

print("After adding boss:")
for i, k in ipairs(t) do
   print(i, k, t[k])


print("After sorting on key:")
for i, k in ipairs(t) do
   print(i, k, t[k])

table.sort(t, function (k1, k2) return t[k1] < t[k2] end)

print("After sorting on value:")
for i, k in ipairs(t) do
   print(i, k, t[k])

xref.del(t, 'last')

print("After deleting last:")
for i, k in ipairs(t) do
   print(i, k, t[k])

-- Output:
After initialization:
1    name    Fred
2    last    Flintstone
After adding boss:
1    name    Fred
2    last    Flintstone
3    boss    Slate
After sorting on key:
1    boss    Slate
2    last    Flintstone
3    name    Fred
After sorting on value:
1    last    Flintstone
2    name    Fred
3    boss    Slate
After deleting last:
1    name    Fred
2    boss    Slate

The information contained in this email transmission may contain proprietary and business 
sensitive information.  If you are not the intended recipient, you are hereby notified that 
any review, dissemination, distribution or duplication of this communication is strictly 
prohibited.  Unauthorized interception of this e-mail is a violation of law.  If you are not 
the intended recipient, please contact the sender by reply email and immediately destroy all 
copies of the original message.

Any technical data and/or information provided with or in this email may be subject to U.S. 
export controls law.  Export, diversion or disclosure contrary to U.S. law is prohibited.  
Such technical data or information is not to be exported from the U.S. or given to any foreign
person in the U.S. without prior written authorization of Elbit Systems of America and the 
appropriate U.S. Government agency.