|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://angg.twu.net/LUA/Set.lua.html
-- http://angg.twu.net/LUA/Set.lua
-- (find-angg "LUA/Set.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- The classes Set and SetL.
--
-- Objects of the class "Set" can be used in two ways: either as sets
-- in the traditional sense or in a way in which the elements of the
-- set are treated as the keys of an associative table and each key is
-- associated to a value. When a Set object is used as a set "in the
-- traditional sense" the keys of the table correspond to the elements
-- of the set and the value associated to each key is the key itself.
--
-- The class SetL is a variant of Set in which we record the order in
-- which the keys were added.
--
-- TODO: document this.
--
-- (find-ydb "ydb2.lua" "SetL")
-- (find-ydb "ydb2.lua" "SetL-tests")
-- (find-fline "~/lakhesys/TODO" "SetL =")
-- (find-es "lua5" "SetL")
-- «.Set» (to "Set")
-- «.Set-tests» (to "Set-tests")
-- «.SetL» (to "SetL")
-- «.SetL-tests» (to "SetL-tests")
-- ____ _
-- / ___| ___| |_
-- \___ \ / _ \ __|
-- ___) | __/ |_
-- |____/ \___|\__|
--
-- «Set» (to ".Set")
-- Also here: (find-angg "LUA/lua50init.lua" "Set")
--
Set = Class {
type = "Set",
new = function () return Set {_={}} end,
from = function (L) return Set.fromarray(L) end,
fromarray = function (L)
local C = Set.new()
for i,v in ipairs(L) do C._[v]=v end
return C
end,
__add = function (A, B) -- union
local C = Set.new()
for k,v in pairs(A._) do C._[k]=v end
for k,v in pairs(B._) do C._[k]=v end
return C
end,
__sub = function (A, B) -- difference
local C = Set.new()
for k,v in pairs(A._) do C._[k]=v end
for k,v in pairs(B._) do C._[k]=nil end
return C
end,
__mul = function (A, B) -- intersection
local C = Set.new()
for k,v in pairs(A._) do if B._[k] then C._[k]=v end end
return C
end,
__len = function (A) print"!" return #(keys(A._)) end, -- number of elements
__tostring = function (A)
return "(Set with "..A:n().." elements)"
end,
--
-- Methods
__index = {
get = function (A, k) return A._[k] end,
has = function (A, k) return A._[k] end,
n = function (A) return #keys(A._) end,
k = function (A) return keys(A._) end,
ks = function (A) return sorted(keys(A._)) end,
ksc = function (A, sep) return table.concat(A:ks(), sep or "\n") end,
gen = function (A)
return cow(function ()
for _,k in ipairs(A:ks()) do coy(k, A:get(k)) end
end)
end,
add = function (A, key, val)
A._[key] = val or key
return A
end,
del = function (A, key)
A._[key] = nil
return A
end,
},
}
-- «Set-tests» (to ".Set-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Set.lua"
tokeyval = function (str)
local k,v = str:match"(.-)->(.*)"
if k then return k,v else return str end
end
Set.__index.adds = function (s, str)
for _,str in ipairs(split(str)) do s:add(tokeyval(str)) end
return s
end
Set.__index.print = function (A) for k,v in A:gen() do print(k.."->"..v) end end
A = Set.new():adds("1 2->22 3->33") -- the "1" works as "1->1"
B = Set.new():adds("3->333 4->444 5->555")
= A
= A:ksc()
PPV(A)
= (A*B):ksc" "
= (A+B):ksc" "
= (A-B):ksc" "
A :print()
B :print()
(A*B):print() -- here the output is "3->33", not "3->333"
(A+B):print() -- note the "3->333" (not "3->33"!) in the output
(A-B):print()
--]]
-- ____ _ _
-- / ___| ___| |_| |
-- \___ \ / _ \ __| |
-- ___) | __/ |_| |___
-- |____/ \___|\__|_____|
--
-- «SetL» (to ".SetL")
-- Also here: (find-angg "LUA/lua50init.lua" "SetL")
--
SetL = Class {
type = "SetL",
new = function () return SetL {keys={}, list={}} end,
from = function (L) return Set.fromarray(L) end,
fromarray = function (L)
local C = Set.new()
for i,k in ipairs(L) do C:add(k) end
return C
end,
__len = function (setl) return setl:n() end,
__tostring = function (setl)
return format("(SetL with %d elements)", setl:n())
end,
__add = function (A, B) -- union
local C = SetL:new()
for k,v in A:gen() do C:add(k, v) end
for k,v in B:gen() do C:add(k, v) end
return C
end,
__mul = function (A, B) -- intersection
local C = SetL:new()
for k,v in A:gen() do if B:has(k) then C:add(k, v) end end
return C
end,
__sub = function (A, B) -- difference
local C = SetL.new()
for k,v in A:gen() do if not B:has(k) then C:add(k, v) end end
return C
end,
--
-- Methods
__index = {
has = function (setl, key) return setl.keys[key] end,
val = function (setl, key) return setl.keys[key] end,
n = function (setl) return #setl.list end,
k = function (setl) return setl.list end,
ks = function (setl) return sorted(keys(setl.keys)) end,
ksc = function (setl, sep) return table.concat(setl:ks(), sep or "\n") end,
gen = function (setl) return cow(function ()
for i,k in ipairs(setl.list) do coy(k, setl:val(k)) end
end) end,
add = function (setl, key, val)
if not setl:has(key) then
setl.keys[key] = val or key
table.insert(setl.list, key)
end
return setl
end,
},
}
-- «SetL-tests» (to ".SetL-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "SetL.lua"
--]]
-- Local Variables:
-- coding: utf-8-unix
-- End: