Is it possible to perform arithmetic on multiple values in Lua.
I am using Lua for windows 5.1.4.
Currently I have to put the multiple values into a table and then unpack them, and I would like to be able to skip that step.
Is it possible.
Here is what I currently have:
function numsToStr(...)
local nums = {}
for i,v in ipairs({...}) do
nums[i] = v + string.byte('A') - 1
end
return string.char(unpack(nums))
end
What I want is to be able to do this
function numsToStr(...)
return string.char(...+string.byte('A')-1)
end
No, it is not possible to do arithmetic on multiple values in Lua.
It's not possible to do "directly", but you can implement "map" function, similar to what you've done. Some relevant resources: Short anonymous functions, thread on Perl-like map/grep functions, and map and other functions. Also take a look at list comprehensions in Penlight.
Related
How do I access a dictionary using a parameter?
In python I can do dictionary.get(param)
Is there an equivalent to this in lua?
I want to do something like this:
function make_object_from_flag(x, y, flag)
local flag_obj = {
[1] = make_impassable_object(x, y),
[2] = make_coin(x,y),
[4] = make_screen_transition_object(x, y),
}
flag_obj.get(flag)
end
Lua only has a single data structure, which is essentially a map (or dictionary) just called "table".
Table indexing in Lua usually works using brackets [], just like python does with arrays.
So basically, as Egor Skriptunoff pointed out in his comment, you want flag_obj[flag] to access the value associated with the key flag in the table flag_obj.
Note though that using bit flags as is done in C is very uncommon and not very performant in Lua, and shouldn't normally be done unless there's some good reason for it.
Is there an idiomatic way to apply a function to all items in a list ?
For example, in Python, say we wish to capitalize all strings in a list, we can use a loop :
regimentNames = ['Night Riflemen', 'Jungle Scouts', 'The Dragoons', 'Midnight Revengence', 'Wily Warriors']
# create a variable for the for loop results
regimentNamesCapitalized_f = []
# for every item in regimentNames
for i in regimentNames:
# capitalize the item and add it to regimentNamesCapitalized_f
regimentNamesCapitalized_f.append(i.upper())
But a more concise way is:
capitalizer = lambda x: x.upper()
regimentNamesCapitalized_m = list(map(capitalizer, regimentNames)); regimentNamesCapitalized_m
What is an equivalent way to call a function on all items in a list in Dart ?
If you want to apply a function to all items in a List (or Iterable) and collect the results, Dart provides an Iterable.map function that is equivalent to Python's map:
// Dart
regimentNamesCapitalized_m = regimentNames.map((x) => x.toUpperCase()).toList();
Python also provides list comprehensions, which usually are considered more Pythonic and often are preferred to the functional approach:
# Python
regimentNamesCapitalized_m = [x.upper() for x in regimentNames]
Dart's equivalent of Python's list comprehensions is collection-for:
// Dart
regimentNamesCapitalized_m = [for (var x in regimentNames) x.toUpperCase()];
If you're calling a function for its side-effect and don't care about its return value, you could use Iterable.forEach instead of Iterable.map. In such cases, however, I personally prefer explicit loops:
I think they're more readable by virtue of being more common.
They're more flexible. You can use break or continue to control iteration.
They might be more efficient. .forEach involves an extra function call per iteration to invoke the supplied callback.
The answer seems to be to use anonymous functions, or pass a function to a lists forEach method.
Passing a function:
void capitalise(var string) {
var foo = string.toUpperCase();
print(foo);
}
var list = ['apples', 'bananas', 'oranges'];
list.forEach(capitalise);
Using an anonymous function:
list.forEach((item){
print(item.toUpperCase());
});
If the function is going to be used only in one place, I think its better to use the anonymous function, as it is easy to read what is happening in the list.
If the function is going to be used in multiple places, then its better to pass the function instead of using an anonymous function.
I am really newbie in lua. I have this lua code
local gun_info = {
g_sword={rate=0.5;spd=0;dmg=1;ammo=1;};
g_pistol={rate=0.5;spd=5;dmg=1;ammo=40;};
g_knife={rate=0.8;spd=5;dmg=1;ammo=1;};
g_shuriken={rate=0.3;spd=5;dmg=1;ammo=40;};
g_bomb={rate=0.8;spd=5;dmg=1;ammo=20;};
};
I just want get values of every ammo. Other properties are no needed.
for k, v in pairs(gun_info) do
print(k, v[1], v[2], v[3], v[4], v[5])
end
this prints out whole tables but I need just value of ammos
Use comma between table variables rather than semicolon. Using semicolon is not syntactically wrong but optional in Lua. Semicolon is usually used to separate multiple statements written in single line.
You can directly access the variable ammo by indexing the key of the table
for k, v in pairs(gun_info) do
print(k, v.ammo)
end
v.ammo and v[ammo] are not same in Lua.
Note: The order in which the elements appear in traversal will not be the same as you defined and can produce different order each time. This is due to the way tables are implemented in Lua.
It seems like there's know such thing as a reference to a number/boolean/lightuserdata in Lua. However, what would be the easiest way to set a global in Lua that points to a C++ native type (e.g. float) and have it update automatically when I change the corresponding global in Lua?
int foo = 2;
//imaginary lua function that does what I want
lua_pushnumberpointer(state,&foo)
lua_setglobal(state,"foo")
-- later, in a lua script
foo = 5;
The last line should automatically update foo on the C++ side. What would be the easiest way to achieve something like this?
Take a look at meta tables, especially the tags __index and __newindex.
If you set them to suitable functions, you have full control what happens when a new index is set / an unset index is queried.
That should allow you to do all you asked for.
It might be advantageous to only set __newindex to a custom function and save the interesting entries in a table set on __index.
Example handler for __newindex and companion definition of __index.
Consider implementing it on the native side though, for performance, and because __hidden_notify_world() is most likely native.
do
local meta = getmetatable(_ENV) or {}
setmetatable(_ENV, meta)
local backing = {}
_ENV.__index = backing
function _ENV:__newindex(k, v)
if backing[k] ~= v then
backing[k] = v
__hidden_do_notify_world(k, v)
end
end
end
If you are using Lua < 5.2 (2011), you must use _G instead of _ENV.
I am trying to modify a collection of arrays inside of a variadic function. I end up working on a copy when trying to add to the arrays and they get lost after the call. Is there any way to pass values by ref in Lua?
function myfunc(...)
local args = {...}
--do work on args--
end
"do work" doesn't actually end up doing anything but it works outside the function just fine.
Obviously I could pass an array of arrays and not use ... but that kinda defeats the purpose of using ...
In Lua, you can't just choose to pass variables by reference or not. Basic types are never passed by reference (like numbers and booleans), others are always passed by reference (like tables, userdata and strings). In the case of strings this does not matter much, because they are immutable anyhow.
So either you pass your arguments you want to work on globally as strings like this:
a=2
b=3
function myfunc(...)
local args={...}
for k,v in pairs(args) do
_G[v]=_G[v]+k
end
end
myfunc('a')
print(a) -- 3
myfunc('a','b')
print(a,b) -- 4 5
Note that this only works on globals, since locals are not kept in a table.
Working with tables makes this kind of things less painful:
function myfunc(t)
for k,v in pairs(t) do
t[k]=v+k
end
end
tab1={a=2}
myfunc(tab1)
print(tab1.a) -- 3
tab2={a=2,b=3}
myfunc(tab2)
print(tab2.a,tab2.b) -- 3 5
The purpose of using ... is grouping the whole parameter list in one varible. That has little to do with the by-reference or by-value nature of the parameters.
All natural types in Lua are passed by value, with tables being the only exception.
The simplest way to do what you want is to pass an array of arrays. If the two extra characters seem like too much typing, know that you can remove the parenthesis instead:
foo({a,b,c})
foo{a,b,c} -- equivalent