I'm trying to get table key name from a value.
tostring only returns table: XXXXXXXXX
I tried some functions but nothing work.
config = {
opt1 = "etc..."
}
players = {}
function openMenu(playerName, configTable)
players[playerName] = Something to get Table Key...
-- read the table and create a gui not yet made
end
And next, if I do this :
print(players[playerName])
I want to get this output :
"config"
You will need to iterate over all pairs of the table and return the key if the value is equal. Note that this will only return one binding, even if multiple keys can lead to the same value:
function find(tbl, val)
for k, v in pairs(tbl) do
if v == val then return k end
end
return nil
end
table.find(t, value [,start_index]) -> [key or nil]
Related
I have some lua code like this:
_table = {
stuff = {
item1 = {Name="Stack",Rarity="Over"};
item2 = {Name="Flow",Rarity="Com"}
};
};
print("placeholder") -- example thing
_stuff = _table.stuff
for i = 1, #_stuff do
print(_stuff[i].Name)
end
The output is this:
placeholder
I've tried to look at stuff but I don't think it was related to my problem.
Lua tables conceptually are "maps": They map keys to values. Your table _table maps the key stuff to the {item1 = ..., item2 = ...} table. Your stuff table maps the string "item1" to the {Name="Stack",Rarity="Over"} table and the string "item2" to the {Name="Flow",Rarity="Com"} table.
The length operator # completely ignores string keys. It returns an integer i such that t[i] ~= nil and t[i+1] == nil. In particular, it returns 0 if there are no integer keys in the table. This is the case for your stuff table: You only have string keys. Thus your loop never runs, as the limit is 0 and i = 1 > 0 already is the case before the first loop iteration.
Put simply, you're trying to iterate over a "dictionary" (a table with string keys) as if it were a list. Lua tables have both a "list part" (integer keys from 1 to n, where usually n = #t) and a "hash part" (of all other keys). The "list part" is empty in your case, so there's nothing for you to iterate over.
To iterate over all key-value pairs of any table (list or dictionary) in an undefined order, use pairs (rather than ipairs or iterating over indices i, which only works for lists):
for itemname, item in pairs(_stuff) do
print(item.Name)
end
If you want a defined order of iteration, either build a second table of keys...
local order = {"item1", "item2"}
for _, key in ipairs(order) do
print(_stuff[key].Name)
end
... or use the integer keys ("list part") of the table:
_table = {
stuff = {
{key = "item1", Name="Stack", Rarity="Over"};
{key = "item2", Name="Flow", Rarity="Com"};
};
};
_stuff = _table.stuff
for _, key in ipairs(order) do
for i = 1, #_stuff do
print(_stuff[i].Name)
end
end
then works as expected.
I have this table in lua:
local values={"a", "b", "c"}
is there a way to return the index of the table if a variable equals one the table entries?
say
local onevalue = "a"
how can I get the index of "a" or onevalue in the table without iterating all values?
There is no way to do that without iterating.
If you find yourself needing to do this frequently, consider building an inverse index:
local index={}
for k,v in pairs(values) do
index[v]=k
end
return index["a"]
The accepted answer works, but there is room for improvement:
Why not exit the loop once the element is found? And why bother copying the entire source table into a new throwaway table?
Usually, this sort of function returns the first array index with that value, not an arbitrary array index with that value.
For arrays:
-- Return the first index with the given value (or nil if not found).
function indexOf(array, value)
for i, v in ipairs(array) do
if v == value then
return i
end
end
return nil
end
print(indexOf({'b', 'a', 'a'}, 'a')) -- 2
For hash tables:
-- Return a key with the given value (or nil if not found). If there are
-- multiple keys with that value, the particular key returned is arbitrary.
function keyOf(tbl, value)
for k, v in pairs(tbl) do
if v == value then
return k
end
end
return nil
end
print(keyOf({ a = 1, b = 2 }, 2)) -- 'b'
If you use Lua for Roblox development, you can use the table.find method:
print(table.find({'a', 'b', 'c'}, 'b'))
I need help to know how to do for use table.insert, and insert elements in to one table that is in to another table. This what i have:
Table = {} --Main table
function InsertNewValues()
local TIME = --Any value, string or integer
local SIGNAL = --Any value, string or integer
table.insert(Table, {TIME, SIGNAL})
end
Ok, this allow me to insert the values of TIME and SIGNAL everytime i call that function, so the table will have:
Table[1][1] = TIME
Table[1][2] = SINGAL
...
Table[...][1] = TIME
Table[...][2] = SIGNAL
BUT ... I need to insert the values of TIME and SIGNAL in to another table that is inside of the table "Table", and that table work as a KEY to refer those values ... TIME and SIGNAL ...
therefore, the resulting table would be the following:
+Table
|
+-[1]othertable
|
+-+[1]TIME - [2]SIGNAL
+-+[1]TIME - [2]SIGNAL
+- ...
|
+-[2]othertable
|
+-+[1]TIME - [2]SIGNAL
+-+[1]TIME - [2]SIGNAL
+- ...
How can i do for do that?
----------------- EDIT -----------------
I have not explained myself well, what I need is:
Given a table called "Table", I need to be able to use "strings" as "keys" within that table. That would be:
-- Name of my "container" table
Table = {}
Values to be introduced
Time = '1 seconds' -- this value can change as desired
Value = 'logic' -- this value can change as desired
Add to my master table "Table", using the string key "RandomName"
-- "RandomName" can change as desired
function AddNewValues ()
table.insert (Table [RandomName], {Time, Value})
end
Every time I call the function "AddNewValues ()", it should add the values present in "Time" and "Value" as a "NEW ENTRY" for that "RandomName".
So the table result may should look like this:
+table -- that contains
+-RandomName-- string key to access
+--"Time,Value"
+--"Time,Value"
+--"Time,Value"
+...
And then, to be able to access the values that are inside that table, using "RandomName" as the key:
function Load()
for key, v in pairs(Table) do
a = Table[key][RandomName][1] -- reference to "Time"
b = Table[key][RandomName][2] -- reference to "Value"
print('Time: ' .. a ..'/' .. 'Value: ' .. b)
end
end
You're just not starting deep enough into the table. When you want the sequence values for the table under the key equaling the value of RandomName, just do:
function Load()
for _, v in ipairs(Table[RandomName]) do
a = v[1] -- reference to "Time"
b = v[RandomName][2] -- reference to "Value"
print('Time: ' .. a ..'/' .. 'Value: ' .. b)
end
end
Answer to original question:
It appears that you want something like this:
Table = { ["[1]othertable"] = {}, ["[2]othertable"] = {} }
table.insert(Table["[1]othertable"], {TIME, SIGNAL})
The keys are "[1]othertable" and "[2]othertable".
You might prefer to use keys like "othertable1" and "othertable2". If you use valid identifiers you can drop some of the syntax:
Table = { othertable1 = {}, othertable2 = {} }
table.insert(Table.othertable1, {TIME, SIGNAL})
In fact, you might prefer to do something similar with TIME and SIGNAL. Instead of positive integer indices, you could use string keys:
Table = { othertable1 = {}, othertable2 = {} }
table.insert(Table.othertable1, {TIME = 12.42, SIGNAL = 3.2})
print(Table.othertable1[1].TIME)
I have one list in redis key store. it's containing date as keyname like this.
key
===
20160429
20160430
20160501
20160502
Now I want to key last 2 keys, for this I am doing following in my lua script.
local data = {};
local keyslist = redis.call('keys', 'stats:day:*');
local key, users, redisData;
-- keyslist = #keyslist.sort(#keyslist, function(a, b) return a[2] > b[2] end);
-- keyslist = #keyslist.sort(#keyslist, function(a,b) if a>b then return true; else return false; end end);
for iCtr = 1, #keyslist do
key = string.gsub(keyslist[iCtr], 'stats:day:','');
redisData = redis.call('hmget', keyslist[iCtr], 'image','video');
table.insert(data, {date=key, imgctr=redisData[1], vidctr=redisData[2]});
if iCtr == 2 then break end
end
but this is returning first 2 records, I need last 2 records (e.g. following keys)
20160501
20160502
How Do I get descending key list?
If I understand you right, you might want to do the following:
local count = 0
for iCtr = #keyslist-1,#keyslist do
count=count+1
--do your stuff
if count == 2 then break end
--or
if iCtr == #keyslist then break end
end
This will start at the penultimate item in the keyslist and then count upwards.
Note, I did not test the code, but it should work..
Sample code for sorting a Lua table:
keylist = {1,2,5,8,3, 5}
-- after the following line keylist will be sorted ascending (default)
table.sort(keylist)
-- this line is equivalent:
table.sort(keylist, function (a,b) return a < b end)
the second parameter is to table.sort is a function that takes two table values and returns true if the first one is smaller than the second one.
To sort a table decending you simply call
table.sort(keylist, function(a,b)return a > b end)
Please keep in mind that you can only use this to sort the table values, not their keys. But as you are using keys in a different context this should solve your problem.
In Lua how would one pop/remove the next item (any order) in a key-value-pair table?
Is this possible without having to iterate using pairs?
There is a primitive function next, you can call next(t,k), where k is a key of the table t, returns a next key in the table, in an arbitrary order, and the value associated with this key.
If k is nil, next(t,k) returns the first element if there is one. So you can iterate the table from calling next(t,nil) and end when the next key is nil.
This is an simple example to demonstrate the use of next:
local t = {a = "va", b = "vb", c = "vc"}
local k,v = next(t,nil)
print(k,v)
k,v = next(t,k)
print(k,v)
k,v = next(t,k)
print(k,v)
k,v = next(t,k)
print(k,v)
Output:
a va
c vc
b vb
nil nil
The global function next is useful here. The docs explain it pretty well in general. To use it iteratively, this is 'key':
You may ... modify existing fields. In particular, you may clear
existing fields.
A simple pop function:
-- removes and returns an arbitrary key-value pair from a table, otherwise nil
local pop = function (t)
local key, value = next(t)
if key ~= nil then
t[key] = nil
end
return key, value
end
Demo:
local test = { "one", c = "see", "two", a = "ayy", b = "bee", "three" }
assert(next(test), "Table was expected to be non-empty")
local key, value = pop(test)
while key do
print(key, value)
key, value = pop(test)
end
assert(not next(test), "Table was expected to be empty")
If you run the demo multiple times, you might see the arbitrariness of the table sequence.