Looking for a Set data structure
Looking for a Set data structure
As the topic says I'm looking for a set data structure.
I need the following functions:
function insert(set, item) -- add item to set
function remove(set, item) -- remove item from set
function contains(set, item) -- returns true if item in set
function count(set) -- returns number of items in set
A set should not have any duplicates so adding something twice is a NOP. My current code uses an array. But I have to search the whole array for insert, remove and contains which isn't ideal. I'm thinking of switching to a table using set[x] = x for insert. But then I have to keep track of the count of items myself.
Is there a mod out there already that provides a set data structure like I need?
PS: I also need something to iterate over the set.
I need the following functions:
function insert(set, item) -- add item to set
function remove(set, item) -- remove item from set
function contains(set, item) -- returns true if item in set
function count(set) -- returns number of items in set
A set should not have any duplicates so adding something twice is a NOP. My current code uses an array. But I have to search the whole array for insert, remove and contains which isn't ideal. I'm thinking of switching to a table using set[x] = x for insert. But then I have to keep track of the count of items myself.
Is there a mod out there already that provides a set data structure like I need?
PS: I also need something to iterate over the set.
Re: Looking for a Set data structure
Why? Can't you just use the size of the table, meaning that you can use table_size(your_set)?But then I have to keep track of the count of items myself.
I'm an admin over at https://wiki.factorio.com. Feel free to contact me if there's anything wrong (or right) with it.
-
- Long Handed Inserter
- Posts: 93
- Joined: Thu May 18, 2017 2:22 pm
- Contact:
Re: Looking for a Set data structure
These guys recommend a table of bools indexed by whatever you want in your set: https://www.lua.org/pil/11.5.html
Re: Looking for a Set data structure
Code: Select all
local set = {}
-- insert
set[item] = true
-- remove
set[item] = nil
--contains
local contains = set[item] -- if returning nil instead of false is OK for you
local contains = set[item] or false -- if you need false instead of nil
--iterating
for item in pairs(set) do
--do something with item
end
- bobingabout
- Smart Inserter
- Posts: 7352
- Joined: Fri May 09, 2014 1:01 pm
- Contact:
Re: Looking for a Set data structure
Bob's Library mod already includes some of those functions.
Add, Remove, Replace (changes 1 item to another but keeps quantity.)
Add, Remove, Replace (changes 1 item to another but keeps quantity.)
Re: Looking for a Set data structure
That's what I came up with too. When not having to manually count the items in the table (due to table_size) all the methods become rather trivial.eduran wrote: ↑Thu Apr 04, 2019 6:36 pmLua tables do pretty much everything you need. If you want a performant count(set) function, increment a counter when inserting and decrement when removing.Code: Select all
local set = {} -- insert set[item] = true -- remove set[item] = nil --contains local contains = set[item] -- if returning nil instead of false is OK for you local contains = set[item] or false -- if you need false instead of nil --iterating for item in pairs(set) do --do something with item end
There is one more method I needed:
-- pick an item from the set if any
next(set)
Re: Looking for a Set data structure
Code: Select all
local next_item = next(set, current_item)
Re: Looking for a Set data structure
Kind of obvious.eduran wrote: ↑Sat Apr 06, 2019 11:52 amUse current_item = nil (or just next(set)) to get the first item. If current_item == last_item, next will return nil. One caveat: you should not assign new items to your set while traversing it.Code: Select all
local next_item = next(set, current_item)
I was surprised that pairs and ipairs does not have this problem. I assumed they would be true iterators but they seem to create a copy first so changes in the table don't affect them.
Re: Looking for a Set data structure
They are affected. It is OK to assign new values to existing keys. That includes assigning nil, so key removal is also fine. Adding new keys while iterating with pairs/ipairs/next will lead to unpredictable behavior and possible an error.
Re: Looking for a Set data structure
Should I deduce from that that a table will resize (and re-hash the entries) as it grows but will never shrink? I've only deleted keys in loops so far.
Re: Looking for a Set data structure
Yes, that it pretty much it. Lua rehashes tables only when inserting a key and the hash array is full. Removing keys does not trigger a rehash. There are ways to force Lua to shrink tables, but by default it does not.