Problem with for k,v in ipairs

I want to use ipairs, to print my table in order. However how can I make it so ipairs still works if the table goes (for instance) 1,2,3,4,6,7,8 or 2,3,4,6,7,9. Basically, is there any way I can print the table in (from smallest to largest) even if they’re not 100% sequential? If I can’t, how else can I do it?

Thanks in advance

table.sort

Table.sort and use normal pairs instead of ipairs?

Edit: When I try to use table.SortByKey(Elements, true) I get this error:

[ERROR] lua/includes/extensions/table.lua:146: attempt to compare two table values

  1. unknown - lua/includes/extensions/table.lua:146
  2. sort - [C]:-1
    3. SortByKey - lua/includes/extensions/table.lua:146
    4. v - addons/cgui/lua/autorun/client/cl_cgui.lua:422
    5. unknown - lua/includes/modules/hook.lua:84

Line 422: table.SortByKey(Elements, true)

Example of PrintTable(Elements):

1:
1 = Total propcount:
2 = 0/1000
3 = 2.2
3:
1 = Ping:
2 = 9 ms
3 = 3.4

If they are indexed by number then there is no need to use the pairs function.
Try this:
[lua]
local str = “”
for i=1, #Elements do
str = str…i…" =
“…table.ToString(Elements*)…”
"
end
print(str)
[/lua]

So I did this:


if PlayerIsSpawned == true then 
		table.SortByKey(Elements, true)
		for i=1, #Elements do
			
			Draws(Elements*[1]..Elements*[2],Order)
			Order = Order + 1.2
			table.insert( Elements*, Order ) 
			
		end
	end
	

This is the Draws function I’m calling: function Draws(Str,Height)


	
function Draws(Str,Height)
local Height = (Height * 15) -- Adds a offset for each setting enabled. 
	
	draw.SimpleText(Str,"HUDFont", ScrW()-(MainWidth)-41, 50+Height , Color(255,255,255), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP) -- Draws the optional values. 
	
end


An example of a Elements table entry:
Elements[5] = {"Session time: ",SessionUTime}

However I’m getting this error:
[ERROR] addons/cgui/lua/autorun/client/cl_cgui.lua:425: attempt to index a nil value

  1. v - addons/cgui/lua/autorun/client/cl_cgui.lua:425
  2. unknown - lua/includes/modules/hook.lua:84

Line 425: Draws(Elements*[1]…Elements*[2],Order)

-snip-

I don’t think this matters but you can try to replace #Elements with table.Count(Elements). If you were indexing a key that didn’t exist it would error out like that but it would work for you up until that point. AKA beyond the bounds of the table, but since lua is 1 indexed table length and max index are one in the same, and you do not need to subtract 1 from the result of the length operator.

EDIT*

It doesn’t help that we can’t see where any of your variable are defined.

needs the count to be successive, if I recall correctly. If its 1, 2, 4, 5, 6 it’ll return 2.

table.Count counts how many entries are in the table.

What I do for non-numeric keyed tables when needing to sort them alphabetically; is create a linked table which has numerical keys, and sort-by-member then. Then pairs( ) still works; but for ipairs( ) you need an iterator function: http://www.lua.org/pil/7.3.html


function DrawHud()

-- Update how many options has enabled and how many admins are online.

UpdateOptions()

-- Find out the users total UTime and session UTime (accurately).

--CurrentUTime = timeToStrTwo( LocalPlayer():GetUTime() + CurTime() - LocalPlayer():GetUTimeStart() )
--SessionUTime = timeToStrMin( CurTime() - LocalPlayer():GetUTimeStart() )

CurrentUTime = 10
SessionUTime = 20


-- An offset to avoid the box being too large if no options are enabled. 

if Options == 0 then
	Offset = 25 
		else 
		Offset = 37 + (Options*2.3)
			end	
			
-- These elements are forced onto the user (the base of CGUI).

	surface.SetFont("HUDFont")
	local MainWidth, MainHeight = surface.GetTextSize( "CGUI - BlueOrifice Build ("..#player.GetAll().."/"..game.MaxPlayers()..")" )
	local Width, Height = surface.GetTextSize("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
	
	draw.RoundedBox(4, ScrW()-(MainWidth+40)-15, 20, MainWidth+40, 25, Color(4,4,4,200))
	draw.RoundedBox(4, ScrW()-(MainWidth+40)-15, 20, MainWidth+40, Offset+(Options*15), Color(4,4,4,200))
	
	
	draw.SimpleText("CGUI - BlueOrifice Build ("..#player.GetAll().."/"..game.MaxPlayers()..")","HUDFont", ScrW()-(MainWidth+23), 32 , Color(255,255,255), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
	
	surface.SetMaterial(Material("icon16/script.png"))
	surface.SetDrawColor(255,255,255)
	surface.DrawTexturedRect(ScrW()-(MainWidth+45), 26,13.5,13.5)


-- These elements are optional to the users

local Elements = {}
local Loading = "Loading..."
local Order = 1

	if Settings[1] == 1 and CGUI_TotalPropCount ~= nil then
		Elements[1] = {"Total propcount: ",CGUI_TotalPropCount.."/"..tostring(GetConVarNumber("sbox_maxprops"))}
	end

	if Settings[2] == 1 and MyPropCount ~= nil then 
		Elements[2] = {"My propcount: ",MyPropCount}	
	end
	
	if Settings[3] == 1 and LocalPing ~= nil then 
		Elements[3] = {"Ping: ",LocalPing.." ms"}	
	end
	
	if Settings[4] == 1 then 
		Elements[4] = {"Total time: ",CurrentUTime}
	end
	
	if Settings[5] == 1 then 
		Elements[5] = {"Session time: ",SessionUTime}
	end
	
	if Settings[6] == 1 then 
		if CGUI_TotalConstraints == nil then
			CGUI_TotalConstraints = 0 
		end
		Elements[6] = {"Total Constraints: ",CGUI_TotalConstraints}
	end
	
	if Settings[7] == 1 then 
		if CGUI_ClientConstraints == nil then
			CGUI_ClientConstraints = 0 
		end
		Elements[7] = {"Your Constraints: ",CGUI_ClientConstraints}
	end
	
	if Settings[8] == 1 then 
		Elements[8] = {"Admins: ",""}
			for k,v in ipairs(AdminTable) do
				Elements[8+k] = {"	-  ", string.sub(AdminTable[k], 0, 20)}
			end
	end

-- Define the drawing function, called later for every element.

function Draws(Str,Height)
	
	local Height = (Height * 15) -- Adds a offset for each setting enabled. 
	
	draw.SimpleText(Str,"HUDFont", ScrW()-(MainWidth)-41, 50+Height , Color(255,255,255), TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP) -- Draws the optional values. 
	
end

-- Draws the predefined elements, checks if the player is spawned to avoid error.


	if PlayerIsSpawned == true then 
		
		for k,v in pairs(Elements) do
			
			Draws(v[1]..v[2],Order)
			Order = Order + 1.2
			table.insert( Elements[k], Order ) 
			
		end
	end
	
-- Draw some exclamation icons next to elements that are too high
PrintTable(Elements)


if MyPropCount != nil then
	if MyPropCount > 10 and Settings[2] == 1 then 
		local CGUI_ErrorOffset = Elements[2][3]
		
		
		draw.RoundedBoxEx( 4, ScrW()-(MainWidth+40)-32, (CGUI_ErrorOffset*15)+17, 17, 16, Color(4,4,4,200),true, false, true, false ) 
		surface.SetDrawColor(255,255,255)
		surface.SetMaterial(Material("icon16/exclamation.png"))
		surface.DrawTexturedRect(ScrW()-(MainWidth+40)-28, (CGUI_ErrorOffset*15)+20,11,11)
	
	end
end 

if CGUI_TotalPropCount != nil then
	if CGUI_TotalPropCount > 10 and Settings[1] == 1 then 
		local CGUI_ErrorOffset = Elements[1][3]
		draw.RoundedBoxEx( 4, ScrW()-(MainWidth+40)-32, (CGUI_ErrorOffset*15)+17, 17, 16, Color(4,4,4,200),true, false, true, false ) 
		surface.SetDrawColor(255,255,255)
		surface.SetMaterial(Material("icon16/exclamation.png"))
		surface.DrawTexturedRect(ScrW()-(MainWidth+40)-28, (CGUI_ErrorOffset*15)+20,11,11)
		
	end
end 

if LocalPing != nil then
	if LocalPing > 20 and Settings[3] == 1 then 
		local CGUI_ErrorOffset = Elements[3][3]
		draw.RoundedBoxEx( 4, ScrW()-(MainWidth+40)-32, (CGUI_ErrorOffset*15)+17, 17, 16, Color(4,4,4,200),true, false, true, false ) 
		surface.DrawTexturedRect(ScrW()-(MainWidth+40)-28, (CGUI_ErrorOffset*15)+20,11,11)
		surface.SetDrawColor(255,255,255)
		surface.SetMaterial(Material("icon16/exclamation.png"))
	end
end

if CGUI_TotalConstraints != nil then
	if CGUI_TotalConstraints > 5 and Settings[6] == 1 then 
		local CGUI_ErrorOffset = Elements[6][3]
		draw.RoundedBoxEx( 4, ScrW()-(MainWidth+40)-32, (CGUI_ErrorOffset*15)+17, 17, 16, Color(4,4,4,200),true, false, true, false ) 
		surface.SetDrawColor(255,255,255)
		surface.SetMaterial(Material("icon16/exclamation.png"))
		surface.DrawTexturedRect(ScrW()-(MainWidth+40)-28, (CGUI_ErrorOffset*15)+20,11,11)
	
	end
end  

end
--Load HUD on tick

hook.Add("HUDPaint", "CGUI_DRAWGUI", DrawHud)


It kinda works with the above code, however when the user enables the ping option and the admin list option only, the list prints in reverse with the Admins name at the top, then Admins: and then Ping:
It should be the opposite, why does this happen?