Get value from key?

How can i get the value of a key in a regular for loop? I know you can get the key from values but i havn’t seen a way to get the value from the key. Any help is greatly appreciated :slight_smile:

getting the key from values is harder, to get the value from a key it’s just

[lua]table[key][/lua]

Yeah i figured that but heres what im trying to do. Basically an optimised way of saying if x <= y and >= z then do stuff.



if tonumber(atk:GetPData("xp", 0)) < tonumber(levels*) then
			atk:SetPData("level", tonumber(i-1))
		end


so what are you actually asking

Its for a level / xp addon

[editline]24th March 2014[/editline]

oh sorry greatest answer right ^. Its to get rid of using if a >= b && a < c then do stuff, and just use a for loop to check if your xp is less than one of the values in the table and if it is it would set your level to the key 1 less than it.

A suggestion unrelated to the question:
Don’t use GetPData like that, it’s a bit expensive so you want to minimize its use as much as possible.

Instead, use a cache value that you periodically update PData with on timed/scheduled intervals.

Same with SetPData.

I prefer to use pdata so i dont have to worry about ever losing the data. Also i have commands to alter the kills / deaths so if something does mysteriously happen i can set it back up. I guess i can find another way to do the checks if its too expensive.

GetPData is not heavy. Neither is SetPData, unless you’re like calling it every frame or something ridiculous. Your method = have fun in the world of data loss.

Btw still no idea what you’re asking, OP.

A standard counted loop would be like so:

[lua]local _table = { 8, 7, 6, 5, 4, 3, 2, 1 };
for i = 1, table.Count( _table ) do
print( "Key: " … tostring( i ) );
print( "Value: " … tostring( _table[ i ] ) );
end[/lua]

And for a foreach loop:
[lua]local _table = { 8, 7, 6, 5, 4, 3, 2, 1 };
for k, v in pairs( _table ) do
print( "Key: " … tostring( k ) );
print( "Value: " … tostring( v ) );
end[/lua]

Ok ill write it descriptively, Normally you would use an if-then statement to check something like this for example:



if a >= b && a < c then
--code
elseif if a >= d && a < e then
--more code
end


Well instead of doing that 50 times for each level im trying to use an alternate method that would be faster. Basically running a for loop to check if A is greater then table* and the one it gets to that isnt bigger then it would set B to the key of the value that was greater than A. Sorry if thats too confusing just look at the code above and kinda visualize it so that a = xp and b = level.

There’s an example I gave not too long ago which helps simplify which gun the player is currently on in a gun-game. Let me grab that link:

The thing is that it needs to be a normal for loop to check if the keys value is greater than the xp and the one that its not greater than would be the 1 - the level.
damn you and your 1 minute posts after mine :v:

I see what you’re asking now but i need to understand the context of it to give you the right answer.

What are you trying to get/do and out of what table, and what is the structure of said table?

This is the table and how its set up.


 
levels = {}
levels[1] = 100
for i=1, 49 do
	table.insert(levels,i+1,math.Round((levels*)*1.2))
end


And its for setting someones level for an exp / level system.

Here are a few things regarding generating XP needed for next level:

https://dl.dropboxusercontent.com/u/26074909/tutoring/levels.lua
https://dl.dropboxusercontent.com/u/26074909/tutoring/levels2.lua
https://dl.dropboxusercontent.com/u/26074909/tutoring/levels3.lua

Just save the level they’re on / save the xp they have. When you check to see if they’re ready for next-level, just check to see if that reference exists ( for the next level ie level + 1 ) and check to see if the current xp is greater than or equal to the value.



levels = {... whatever your code}

local player_xp = player's xp
local player_level = 0

for level, xp_required in ipairs(levels) do
    if player_xp < xp_required then
        break -- Stop loop, player doesn't have enough XP for this level or any higher levels
    end

    player_level = level
end


This will loop through every level in order and if the player has enough xp, set player_level to that level until the levels require more XP than the player has.

This assumes that levels[level] is equal to the total XP needed to reach that level.

Using a loop to determine level wouldn’t be a good design.

Use the key as the level, and the value is the xp required to obtain that level.

Store the total xp, store the current level.

When you do a check to see if they can level up it’s a simple query:
[lua]local Levels = { 100, 200, 400, 800, 1600, 3200, 6400 };

if ( Levels[ Player.Level + 1 ] && Player.EXP >= Levels[ Player.Level + 1 ] ) then
Player.Level = Player.Level + 1;
// Spawn effects, do whatever…
end
[/lua]

That assumes you already have their level. My code assumes you are trying to find the level from the XP alone.

Ok, so if you don’t have the level then level = 1. If you don’t have the xp, then xp = 0. Initialize the variables. When you connect to the server the saved values should be obtained, OR initialized.

You would need to use a loop only if the table changes ( xp for each level )

Sure, the only issue is if for some reason a player earns more XP than necessary and should level up twice which is easily possible with admin intervention.