Jump to content

Difference between two tables


Bilal135

Recommended Posts

I'm trying to find the difference between two tables. For e.g, if I have two tables, one with all players online in the server, and the other who are currently typing (have their chat box input active). I want to return a new table that would contain all players except the players who are typing.

The code below should output the names of those players who are NOT typing at the moment, but it outputs names of even those players who are typing. I have already got the players who are typing, in a table, called 'my_player_list'.

function difference(a, b)
   local aa = {}
   for k,v in pairs(a) do aa[v]=true end
   for k,v in pairs(b) do aa[v]=nil end
   local ret = {}
   local n = 0
   for k,v in pairs(a) do
       if aa[v] then n=n+1 ret[n]=v end
   end
   return ret
end

addEventHandler("onClientRender", root, function() -- using onClientRender here because I'm going to use dxDraw functions here 
   local playerTable = getElementsByType("player")
   rTable = difference(playerTable, my_player_list) -- my_player_list is a table which contains players who are typing
   for i, v in pairs(rTable) do
      if (v) then
      outputChatBox(""..getPlayerName(v).."")
      end
   end
end)

Thanks.

 

Link to comment

Just do something like this, it should work just fine:

function difference(a,b)
	-- This should put everything that is on table A and it isn't on table B into a new indexed table
	local ret = {}
	for k,v in pairs(a) do
		local insert = true
		for k2,v2 in pairs(b) do
			if v == v2 then
				insert = false
				break;
			end
		end
		if insert then
			table.insert(ret, v)
		end
	end
  	return ret
end

If you want to go the way you code went then you should do something like this:

function difference(a,b)
	local aa = {}
	for k,v in pairs(a) do 
		aa[v]=true
	end
	for k,v in pairs(b) do
		aa[v]=nil
	end
	
	local ret = {}
	for k,v in pairs(aa) do
		table.insert(ret, v)
	end
	return ret
end

However I don't think you should use this (if it even works) because you just run too much stuff without it being really needed to be, and it's kinda pointless.

Edited by Platin - xNikoXD
I forgot the return, and I added something else
Link to comment
addEventHandler("onClientRender", root, function()
    
   local playerTable = getElementsByType("player")

   rTable = difference(playerTable, my_player_list)

   for i, v in pairs(rTable) do
      if (v) then
      outputChatBox(""..getPlayerName(v).."")


      local px, py, pz, tx, ty, tz, dist
      px, py, pz = getCameraMatrix( )
         tx, ty, tz = getElementPosition( v )
         dist = math.sqrt( ( px - tx ) ^ 2 + ( py - ty ) ^ 2 + ( pz - tz ) ^ 2 )
         if dist < 60.0 then
            if isLineOfSightClear( px, py, pz, tx, ty, tz, true, false, false, true, false, false, false,localPlayer ) then
               local sx, sy, sz = getPedBonePosition( v, 6 )
               local x,y = getScreenFromWorldPosition( sx, sy, sz + 0.2 )
	           local playerR, playerG, playerB = getPlayerNametagColor ( v )			   		   
               if x then
                dxDrawBorderedText( string.gsub ( getPlayerName ( v ), "#%x%x%x%x%x%x", "" ).."", x, y, x, y, tocolor(playerR, playerG, playerB), 1.1, "default-bold", "center", "center" )
               end
            else return
            end
         end
      end
   end
end)

How else would you approach this then? element datas maybe? 

Edited by Lynch
Link to comment

Never, really never never never element datas if you will edit them every frame, you will just lag the client (and if synced) the entire server.

The above code is ok, but I would personally make this changes:

addEventHandler("onClientRender", root, function()
	-- Using getElementsByType("player", root, true) instead of getElementsByType("player") will give us only the users that the client is streaming in
	local rTable = difference(getElementsByType("player", root, true), my_player_list)
	
	-- This would be the same for the entirety of the frame, you don't need to update it for every player, so just let it seat outside
	local px, py, pz = getCameraMatrix( )
	
	-- We should use ipairs, because our table is indexed properly, this should decrease usage of... cpu? ig
	for i, v in ipairs(rTable) do
		-- i don't know why you have this check here, but if you want to check if V is an element, use this:
		if isElement(v) then
			local tx, ty, tz = getElementPosition( v )
			local dist = math.sqrt( ( px - tx ) ^ 2 + ( py - ty ) ^ 2 + ( pz - tz ) ^ 2 )
			if dist < 60.0 then
				if isLineOfSightClear( px, py, pz, tx, ty, tz, true, false, false, true, false, false, false, localPlayer) then
					local sx, sy, sz = getPedBonePosition( v, 6 )
					local x,y = getScreenFromWorldPosition( sx, sy, sz + 0.2 )
					-- You shouldn't store variables if they won't vary, if possible ofc
					if x then
						dxDrawBorderedText( string.gsub ( getPlayerName ( v ), "#%x%x%x%x%x%x", "" ).."", x, y, x, y, tocolor(getPlayerNametagColor(v)), 1.1, "default-bold", "center", "center" )
					end
				-- If you return here, you won't be drawing anyone else if the check fails
				end
			end
		end
	end
end
)

 

Edited by Platin - xNikoXD
minor update
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...