local t={}
for i,v in pairs(game.Players:GetPlayers()) do
if v~=game.Players.LocalPlayer then
table.insert(t,v.Name)
end
end
if i do table.foreach(t,print) it also shows the index and it causes problems when i want to select a random player. The error usually tends to be something like "1 is not a valid member of workspace"
Your problem is not that table.insert adds an index, but that you use it instead of the value you want do use.
table.insert inserts an element to a list. If no index is given the value is added to the end of the list.
So there is no way to use table.insert without "inserting the index". Actually there is no way at all to add an element to a Lua table without providing a key. A Lua table is nothing but a set of key value pairs.
table.foreach calls a function for each key value pair.
You should rather use table.foreachi btw.
So table.foreachi(t, print) is equivalent to
print(1, t[1])
print(2, t[2])
...
If you just want to print the values:
for i,v in ipairs(t) do print(v) end
or for older Lua versions
table.foreachi(t, function(i,v) print(v) end)
Alternatively you run a numeric for loop:
for i = 1, t.n do print(t[i]) end
or
for i = 1, #t do print(t[i]) end
table.foreach(t,f) applies the function f to each key-value pair of t as is written. Also, since Lua 5.1 the function is deprecated.
If you want simply to print all values, do
for _, name in ipairs (t) do
print (name)
end
or
print (table.concat (t, ', '))
If you want a random name from t:
local random_name = t [math.random (#t)]
Related
I'm trying to delete a key and value from a table when it is found in another table. I've been using this so far but although it recognizes the duplicate, it always removes the last item in the table...
function get_key_for_value( t, value )
for k,v in pairs(t) do
if v==value then return k
end
return nil
end
end
for k,v in pairs (Iranian_Protected_Groups) do
v[6] = 0
if Springfield_3_Target_Name == v[2] then
v[6] = v[6] + 1
if v[6] > 0 then
local Key_To_Remove = get_key_for_value (Iranian_Protected_Groups, v)
MESSAGE:New( "Shared target is "..v[2], 40):ToBlue()
table.remove (Iranian_Protected_Groups, Key_To_Remove)
end
end
end
any help would be appreciated!
First, you should format your code using standard indentation to make it easier to parse as a human reading the code:
function get_key_for_value(t, value)
for k, v in pairs(t) do
if v == value then
return k
end
return nil
end
end
Look carefully at the for loop. You will never get past the first iteration, because every iteration returns.
Your function is fixed if you move your return nil statement outside the loop. (Though for most purposes, is redundant, because generally no value is equivalent to returning nil).
Before, Key_To_Remove was nil. When passing nil as the index to remove in table.remove, Lua removes the last element. This is convenient when treating a list like a stack, but hid a bug for you in this case.
currently I am trying to export and re-import some variables in LUA.
Imagine a table AllGlobals. The table contains all global variables used in my script, while key contains the variable name and value - surprise - contains the variable value.
What my script should do now is a reassignment of the variables. I started thinking about the following solution, which obviously isn't working:
1 function InsertGlobals()
2 for key,value in pairs(AllGlobals) do
3 key = value
4 end
5 end
Well: Does anybody know a solution for assigning the value in line 3 to the variable name contained in key, not inserting it into the variable key itself?
Solution to my own problem:
function InsertGlobals()
for key,value in pairs(AllGlobals) do
_G[key]=value
end
end
You are only doing a shallow iteration - you don't transverse over tables in tables. For example, the table input wouldn't put something like examp.newfunc() into the _G as _G.examp.newfunc(). Also, it isn't wise to duplicate references of _G, package, and _ENV unless you really know what you are doing, meaning having a purpose.
function InsertGlobals(input)
for key, value in pairs(input) do
if(key ~= "_G" or key ~= "package" or key ~= "_ENV")then
_G[key] = value
end
end
end
To fix the shallow iteration, all you need to do is a little recursion. I am sure you won't blow your stack with this, but if you leave _G, package, and _ENV then you definitely will.
function InsertGlobals(input)
for key, value in pairs(input) do
if(key ~= "_G" or key ~= "package" or key ~= "_ENV")then
if(type(value) ~= "table")then
_G[key] = value
else
InsertGlobals(value)
end
end
end
end
I am stuck trying to make the contese of a table (all integers) add together to form one sum. I am working on a project where the end goal is a percentage. I am putting the various quantities and storing them in one table. I want to then add all of those integers in the table together to get a sum. I haven't been able to find anything in the standard Library, so I have been tyring to use this:
function sum(t)
local sum = 0
for k,v in pairs(t) do
sum = sum + v
end
return sum
However, its not giving me anything after return sum.... Any and all help would be greatly appreciated.
A more generic solution to this problem of reducing the contents of a table (in this case by summing the elements) is outlined in this answer (warning: no type checking in code sketch).
If your function is not returning at all, it is probably because you are missing an end statement in the function definition.
If your function is returning zero, it is possible that there is a problem with the table you are passing as an argument. In other words, the parameter t may be nil or an empty table. In that case, the function would return zero, the value to which your local sum is initialized.
If you add print (k,v) in the loop for debugging, you can determine whether the function has anything to add. So I would try:
local function sum ( t ) do
print( "t", t ) -- for debugging: should not be nil
local s = 0
for k,v in pairs( t ) do
print(k,v) --for debugging
s = s + v
end
return s
end
local myTestData = { 1, 2, 4, 9 }
print( sum( myTestData) )
The expected output when running this code is
t table: [some index]
1 1
2 2
3 4
4 9
16
Notice that I've changed the variable name inside the function from sum to s. It's preferable not to use the function name sum as the variable holding the sum in the function definition. The local sum in the function overrides the global one, so for example, you couldn't call sum() recursively (i.e. call sum() in the definition of sum()).
I want to know how to get the table hex id. I know that doing:
local some_var = {}
print (some_var)
the result is (for instance):
table: 0x21581c0
I want the hex without the table: string. I know that maybe some of you suggest me to make a regular expression (or something similar) to remove those chars, but I want to avoid that, and just get the 0x21581c0
Thanks
This is simpler and works for all types that are associated with pointers:
local function getId(t)
return string.format("%p", t)
end
print("string:", getId("hi"))
print("table:", getId({}))
print("userdata:", getId(io.stdin))
print("function:", getId(print))
print("number:", getId(1))
print("boolean:", getId(false))
print("nil:", getId(nil))
Result:
string: 0x0109f04638
table: 0x0109f0a270
userdata: 0x01098076c8
function: 0x0109806018
number: NULL
boolean: NULL
nil: NULL
In the standard implementation, there is the global 'print' variable that refers to a standard function that calls, through the global variable 'tostring', a standard function described here. The stanard 'tostring' function is the only way to retrieve the hexadecimal number it shows for a table.
Unfortunately, there is no configuration for either of the functions to do anything differently for all tables.
Nonetheless, there are several points for modification. You can create you own function and call that every time instead, or point either of the the global variables print or tostring to you own functions. Or, set a __tostring metamethod on each table you need tostring to return a different answer for. The advantage to this is it gets you the format you want with only one setup step. The disadvantage is that you have to set up each table.
local function simplifyTableToString(t)
local answer = tostring(t):gsub("table: ", "", 1)
local mt = getmetatable(t)
if not mt then
mt = {}
setmetatable(t, mt)
end
mt.__tostring = function() return answer end
end
local a = {}
local b = {}
print(a, b)
simplifyTableToString(a)
print(a, b)
Without complex patterns, you can just search for the first space, and grab the substring of what follows.
function get_mem_addr (object)
local str = tostring(object)
return str:sub(str:find(' ') + 1)
end
print(get_mem_addr({})) -- 0x109638
print(get_mem_addr(function () end)) -- 0x108cf8
This function will work with tables and functions, but expect errors if you pass it anything else.
Or you can use a little type checking:
function get_mem_addr (o)
return tostring(o):sub(type(o):len() + 3)
end
The table id stated by the OP is invalid in the version of Lua I am using (5.1 in Roblox). A valid ID is length 8, not 9 as in your example. Either way, just use string.sub to get the sub-string you are after.
string.sub(tostring({}), 8)
The reason is, 'table: ' is 7 characters long, so we take from index 8 through the end of the string which returns the hex value.
This question already has an answer here:
lua: iterate through all pairs in table
(1 answer)
Closed 8 years ago.
I am trying to initialize and print a table. It just isnt working. Any idea what is wrong with this code?
--!/usr/bin/env lua
local retv = {}
retv["test"] = 1000
for k,v in ipairs(retv) do
print (k,v)
end
It prints nothing. I am sure I am missing something very basic but I cant figure this out.
There are two forms of the for-loop in Lua:
The numeric and the generic for-loop.
ipairs(t) is an iterator constructor returning up to three arguments suitable for the generic for, allowing you to iterate over the initial sequence (indices 1,2,3,...) in order.
Possible implementations:
function ipairs(t)
local i = 0
return function()
i = i + 1
if t[i] ~= nil then
return i, t[i]
end
end
end
local function ipairs_helper(t, i)
i = i + 1
if t[i] ~= nil then
return i, t[i]
end
end
function ipairs(t)
return ipairs_helper, t, 0
end
As you can see, that will never return your entry with key "test".
What you want instead, is pairs(t), which is equivalent to next, t.
That will iterate all elements.
You need to use pairs instead of ipairs. pairs iterates over all keys, ipairs only iterates over keys that form a sequence of integers starting from 1 without gaps. (Whether these keys are stored in the array or the hash part of the table is an implementation detail and may change during the lifetime of the table.)
For example, ipairs({'a', 'b', nil, 'c'}) iterates over keys 1 and 2, stopping at (and not including) 3, as that key is missing from the table.