Check if an element already exists in a table

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Check if an element already exists in a table

Post 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.
"I don't know."
User avatar
veethree
Inner party member
Posts: 877
Joined: Sat Dec 10, 2011 7:18 pm

Re: Check if an element already exists in a table

Post by veethree »

Something like this should work.

Code: Select all

if not self.targets[v] then
table.insert(self.targets,v)
end
User avatar
BruceTheGoose
Citizen
Posts: 76
Joined: Sat Sep 20, 2014 2:54 pm

Re: Check if an element already exists in a table

Post by BruceTheGoose »

Negative, I still get the same results.
"I don't know."
User avatar
Azhukar
Party member
Posts: 478
Joined: Fri Oct 26, 2012 11:54 am

Re: Check if an element already exists in a table

Post 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
User avatar
Ortimh
Citizen
Posts: 90
Joined: Tue Sep 09, 2014 5:07 am
Location: Indonesia

Re: Check if an element already exists in a table

Post 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.
Last edited by Ortimh on Mon Nov 10, 2014 8:13 am, edited 1 time in total.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Check if an element already exists in a table

Post 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

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
Azhukar
Party member
Posts: 478
Joined: Fri Oct 26, 2012 11:54 am

Re: Check if an element already exists in a table

Post by Azhukar »

Ortimh wrote:you can't index a table with a table.
Wrong.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Check if an element already exists in a table

Post 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.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
User avatar
Azhukar
Party member
Posts: 478
Joined: Fri Oct 26, 2012 11:54 am

Re: Check if an element already exists in a table

Post 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.
User avatar
s-ol
Party member
Posts: 1077
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

Re: Check if an element already exists in a table

Post 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.

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
  baby:hurt(me)
end
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 1 guest