Page 1 of 2
Check if an element already exists in a table
Posted: Sun Nov 09, 2014 11:58 pm
by BruceTheGoose
Code: Select all
function Tower.getAllNear(self)
local distance,nearest
local shortestDistance = self.range
for _,v in ipairs(Troop) do
distance = self:getSquaredDistance(v)
if distance <= shortestDistance then
if self.targets[v] == nil then
table.insert(self.targets,v)
elseif self.targets[v] ~= nil then
print("already exists!")
end
end
end
end
I'm trying to check if an element already exists with in the table self.targets so that the same element doesn't keep getting inserted. However, the above code doesn't seem to get the job done. I do not receive the output and the same element continues to get inserted into the table.
Re: Check if an element already exists in a table
Posted: Mon Nov 10, 2014 12:17 am
by veethree
Something like this should work.
Code: Select all
if not self.targets[v] then
table.insert(self.targets,v)
end
Re: Check if an element already exists in a table
Posted: Mon Nov 10, 2014 12:47 am
by BruceTheGoose
Negative, I still get the same results.
Re: Check if an element already exists in a table
Posted: Mon Nov 10, 2014 3:01 am
by Azhukar
table.insert(self.targets,v) inserts value v at the beginning of your table.
"self.targets[v] == nil" checks whether any value exists at key v.
You mixed up values and keys.
I'm guessing you want your value to exist only once in your table. In that case you can simply use the value itself as a key for the table its in.
So your code would look something like this:
Code: Select all
if self.targets[v] == nil then
self.targets[v] = true
else
print("already exists!")
end
And you would iterate over self.targets like this:
Code: Select all
for v in pairs(self.targets) do
print(v)
end
Re: Check if an element already exists in a table
Posted: Mon Nov 10, 2014 7:28 am
by Ortimh
It loops one time if you call the function, right? So why the same element inserted again? Does it loop again somewhere else? But what about
restart the
self.targets? I mean you remove all values within
self.targets then refill it with nearest target. It may help.
Code: Select all
function Tower.getAllNear(self)
self.targets = {}
for index, value in ipairs(Troop) do
if (self:getSquaredDistance(value) <= self.range) then
table.insert(self.targets, value)
end
end
end
You shouldn't make a new variable if it only used one time like
distance and
shortestDistance. Also
nearest made for nothing.
EDIT:
Maybe you should make a new local table then insert nearest targets which may help better.
Code: Select all
function Tower.getAllNear(self)
local nearest = {}
for index, troop in ipairs(Troop) do
if (self:getSquaredDistance(troop) <= self.range) then
table.insert(nearest, troop)
end
end
return nearest
end
Azhukar, values for
Troop that he loops maybe return a table so you can't index a table with a table.
Re: Check if an element already exists in a table
Posted: Mon Nov 10, 2014 7:53 am
by s-ol
Ortimh wrote:It loops one time if you call the function, right? So why the same element inserted again? Does it loop again somewhere else? But what about
restart the
self.targets? I mean you remove all values within
self.targets then refill it with nearest target. It may help.
Code: Select all
function Tower.getAllNear(self)
self.targets = {}
for index, value in ipairs(Troop) do
if (self:getSquaredDistance(value) <= self.range) then
table.insert(self.targets, value)
end
end
end
You shouldn't make a new variable if it only used one time like
distance and
shortestDistance. Also
nearest made for nothing.
maybe some of the variables are leftover from his actual code in the cleanup process. Nevertheless Azhukar is right, you mixed up values and keys. table.insert() is useless btw
Re: Check if an element already exists in a table
Posted: Mon Nov 10, 2014 1:46 pm
by Azhukar
Ortimh wrote:you can't index a table with a table.
Wrong.
Re: Check if an element already exists in a table
Posted: Mon Nov 10, 2014 2:07 pm
by s-ol
Azhukar wrote:Ortimh wrote:you can't index a table with a table.
Wrong.
It
does lead to problems when the table moves out of scope in the meantime though, so I suggest serializing to a string (table.join()) or keeping an index from a more permanent table if needed.
Re: Check if an element already exists in a table
Posted: Mon Nov 10, 2014 2:16 pm
by Azhukar
S0lll0s wrote:It does lead to problems when the table moves out of scope in the meantime though, so I suggest serializing to a string (table.join()) or keeping an index from a more permanent table if needed.
Wrong.
A table does not get garbage collected when it exists as a key in a non-weak key table. I'm guessing this is what you meant because talking of scope does not even make sense in this situation.
In case it is a weak-key table the keys that are references to garbage collected tables get removed on garbage collection.
Re: Check if an element already exists in a table
Posted: Mon Nov 10, 2014 2:29 pm
by s-ol
Azhukar wrote:S0lll0s wrote:It does lead to problems when the table moves out of scope in the meantime though, so I suggest serializing to a string (table.join()) or keeping an index from a more permanent table if needed.
Wrong.
A table does not get garbage collected when it exists as a key in a non-weak key table. I'm guessing this is what you meant because talking of scope does not even make sense in this situation.
In case it is a weak-key table the keys that are references to garbage collected tables get removed on garbage collection.
Maybe the "out of scope" part is wrong, but I had this issue in a nother project, I had two different table "ids" (the memory address) but the same output on serialization.