navigate table without using pairs in Lua - lua

Hello im a newbie in Lua i just want to know if there is a way to get key and value of table not using pairs,ipairs,next or other iterators? thanks in advance.!

I don't believe this is possible, as you've phrased your question in such a way that implies that the key is unknown. The only way to check for a certain value and its corresponding key would be to iterate through the whole table.
However, maybe I misunderstood and you want to get a certain value from a key without iterating through the whole table.
Say you have a table named morse as follows:
morse = { a = ".-"; b = "-..."; } -- And so on
If you wanted to convert a single character to morse you could do as follows:
morse["a"] --Which will return the string ".-"
You can do the opposite, and define a table with all the morse values and their corresponding letters like below. Note the use of square brackets to 'escape' the characters.
morse = { [".-"] = "a"; ["-..."] = "b" }
morse[".-"] -- This will return "a"

Based on your comment, I think you are looking for a string substitution using a mapping table. I think you can use string.gsub here (if your teacher still insists that .gsub is an iterator; you can ask them politely that you are unaware of the method they claim and would be delighted to actually learn about the same):
local str = "sos sos sos"
local morse = {s = "...", o = "---"}
print( str:gsub("%a", morse) )

Related

Lua/print table error : ( attempt to concatenate a table value)

I got a simple code like:
table = {}
print(table.."hello")
then got a error like the title. I know i need to use tostring(table) to fix it . Why table or other types can't convert to string to concatenate a String automatically except number type ?
print(table) is available But print(table.."hello") is not .
Does lua have some rules?
Thanks you.
Why table or other types can't convert to string to concatenate a String automatically except number type?
This is a deliberate choice made by the Lua language designers. Strings and numbers are coerced: Every operation that expects a string will also accept a number and tostring it; every operation that expects a number will also accept a string and tonumber it.
Coercion is an operation applied to strings. Numbers will be tostringed. Any other type won't. For other primitive types like bools and nils this is somewhat questionable, since they can be converted to string without issue. For tables it's reasonable though since they are a reference type.
Unlike other languages which make such decisions for you, Lua is highly metaprogrammable: You can simply override the decision! In this case, metatables are the solution, specifically the __concat metamethod which gets called if concatenation (..) is applied to two values of which one has the metamethod (and is neither a string or number):
table = setmetatable({}, {
__concat = function(left, right)
if type(left) == "string" then
return left .. tostring(right)
end
return tostring(left) .. tostring(right)
end
})
print(table .. "hello") -- hellotable: 0x563eb139bea0
You could even extend this to primitive types (nils, booleans), some other reference types (functions, coroutines) using debug.setmetatable, but I'd advise against this.
The declaration of table = {} destroying the table library
The datatype table is not a string or number so concat with .. must fail
Try this instead...
mytab = {}
table.insert(mytab, "hello")
print(table.concat(mytab))
For the table library functions look: https://www.lua.org/manual/5.4/manual.html#6.6

Generate Random String with Specific Restrictions

Tring to generate a random string but it needs to be formatted a specific way.
N = number
L = Capital Letter
must be NL-NN
needs hyphen as well
examples: 5K-22, 9L-19, 0R-66
every method I have tried has just generated a string but without the hyphen, I know it is probably something simple my brain just hurts thinking on it so I thought I'd see if one of yall could give me a hand.
Thanks
Try this:
function randomchar(a,b)
return string.char(math.random(string.byte(a),string.byte(b)))
end
a=randomchar('0','9')
b=randomchar('A','Z')
c=randomchar('0','9')
d=randomchar('0','9')
print(a..b..'-'..c..d)

can you use a colon in a key for a lua table

So I'm writing a program for the minecraft mod computercraft. I wanted to know if it was possible to do something like this:
tbl = {}
var = "minecraft:dirt"
tbl[var] = {pos ={0,0,0,1}}
For some reason I feel it doesnt save this table correctly so when I go to do
print(tbl["minecraft:dirt"].pos[4])
it errors
Can you use colons in keys?
tbl = {}
var = "minecraft:dirt"
tbl[var] = {pos ={0,0,0,1}}
print(tbl["minecraft:dirt"].pos[4])
prints 1
This is syntactically correct and should not result in any error message.
The only thing that won't work with colon is the syntactic sugar tbl.minecraft:dirt as Lua names may not contain colons. But if you use it like that tbl["minecraft:dirt"] colon is perfectly fine.
Long story short: Yes you can use colons in table keys.

Break strings into substrings based on delimiters, with empty substrings

I am using LUA to create a table within a table, and am running into an issue. I need to also populate the NIL values that appear, but can not seem to get it right.
String being manipulated:
PatID = '07-26-27~L73F11341687Per^^^SCI^SP~N7N558300000Acc^'
for word in PatID:gmatch("[^\~w]+") do table.insert(PatIDTable,word) end
local _, PatIDCount = string.gsub(PatID,"~","")
PatIDTableB = {}
for i=1, PatIDCount+1 do
PatIDTableB[i] = {}
end
for j=1, #PatIDTable do
for word in PatIDTable[j]:gmatch("[^\^]+") do
table.insert(PatIDTableB[j], word)
end
end
This currently produces this output:
table
[1]=table
[1]='07-26-27'
[2]=table
[1]='L73F11341687Per'
[2]='SCI'
[3]='SP'
[3]=table
[1]='N7N558300000Acc'
But I need it to produce:
table
[1]=table
[1]='07-26-27'
[2]=table
[1]='L73F11341687Per'
[2]=''
[3]=''
[4]='SCI'
[5]='SP'
[3]=table
[1]='N7N558300000Acc'
[2]=''
EDIT:
I think I may have done a bad job explaining what it is I am looking for. It is not necessarily that I want the karats to be considered "NIL" or "empty", but rather, that they signify that a new string is to be started.
They are, I guess for lack of a better explanation, position identifiers.
So, for example:
L73F11341687Per^^^SCI^SP
actually translates to:
1. L73F11341687Per
2.
3.
4. SCI
5. SP
If I were to have
L73F11341687Per^12ABC^^SCI^SP
Then the positions are:
1. L73F11341687Per
2. 12ABC
3.
4. SCI
5. SP
And in turn, the table would be:
table
[1]=table
[1]='07-26-27'
[2]=table
[1]='L73F11341687Per'
[2]='12ABC'
[3]=''
[4]='SCI'
[5]='SP'
[3]=table
[1]='N7N558300000Acc'
[2]=''
Hopefully this sheds a little more light on what I'm trying to do.
Now that we've cleared up what the question is about, here's the issue.
Your gmatch pattern will return all of the matching substrings in the given string. However, your gmatch pattern uses "+". That means "one or more", which therefore cannot match an empty string. If it encounters a ^ character, it just skips it.
But, if you just tried :gmatch("[^\^]*"), which allows empty matches, the problem is that it would effectively turn every ^ character into an empty match. Which is not what you want.
What you want is to eat the ^ at the end of a substring. But, if you try :gmatch("([^\^])\^"), you'll find that it won't return the last string. That's because the last string doesn't end with ^, so it isn't a valid match.
The closest you can get with gmatch is this pattern: "([^\^]*)\^?". This has the downside of putting an empty string at the end. However, you can just remove that easily enough, since one will always be placed there.
local s0 = '07-26-27~L73F11341687Per^^^SCI^SP~N7N558300000Acc^'
local tt = {}
for s1 in (s0..'~'):gmatch'(.-)~' do
local t = {}
for s2 in (s1..'^'):gmatch'(.-)^' do
table.insert(t, s2)
end
table.insert(tt, t)
end

Google Spreadsheet Translate, ignore variable names

An interesting Google Spreadsheet problem, I have a language file based on key=value that I have copied into a spreadsheet, eg.
titleMessage=Welcome to My Website
youAreLoggedIn=Hello #{user.name} you are now logged in
facebookPublish=Facebook Publishing
I have managed to split the key / value into two columns, and then translate the value column, and re-join it with the keys and Voila! this gives me a translated language file back
But as you may have spotted there are some variable in there (eg. #{user.name}) which are injected by my application, obviously I dont want to translate them.
So here is my question, given the following cell contents...
Hello #{user.name} you are now logged in
Is there a function that will translate the contents using the TRANSLATE function, but ignore anything inside #{ } (this could be at any point in the sentance)
Any Google Spreadsheet guru's have a solution for me?
Many thanks
If there are at most one occurrence of #{} then you could use the SPLIT function to divide the string into three parts that are arranged as below.
A B C D E
Original =SPLIT(An, "#{}") First piece Tag Rest of string
Translate Keep as is Translate
Put the pieces together with CONCATENATE.
=CONCATINATE(Cn,Dn,En)
I come up with same question.
Assume the escape pattern is #{sth.sth}(in regex as #{[\w.]+}). Replace them with string which Google Translate would view as untranslatable term, like VAR.
After translation, replace the term with original pattern.
Here is how I did this in script editor of spreadsheet:
function myTranslate(text, source_language, target_language) {
if(text.toString()) {
var str = text.toString();
var regex = /#{[\w.]+}/g; // g flag for multiple matches
var replace = 'VAR'; // Replace #{variable} to prevent from translation
var vars = str.match(regex).reverse(); // original patterns
str = str.replace(regex, replace);
str = LanguageApp.translate(str, source_language, target_language);
var ret = '';
for (var idx = str.search(replace); idx; idx = str.search(replace)) {
ret += str.slice(0, idx) + vars.pop();
str = str.slice(idx+replace.length);
}
return ret;
}
return null;
}
You can't just split and concatenate, because different languages use different word order of subject/predicate/object etc., and also because several languages modify nouns with different prefixes/suffixes/spelling changes depending on what they are doing in the sentence. It's all very complicated. Google needs to enable some sort of enclosing parentheses around any term we want to be quoted rather than translated.

Resources