My professor taught me this (below), for creating a 10 numbers table, but
v = {}
for i = 1, 10 do
v[i] = i
end
print(v[3])
(the output will get me 3, as expected)
why do I recieve "nill" if I try doing this? (bellow)
v = {}
for i = 1, 10, 2 do
v[i] = i
end
print(v[42])
As you can see, I was trying to make a table like this
v = {1,3, 5, 7, 9}
Why it is not working? :(
<3
You're filling only the odd-numbered positions.
Try
for i = 1,5 do
v[i] = 2*i-1
end
Related
Having some Lua trouble with a a modification of Fisher-Yates shuffle in place. For example, let's say I have a 16 item table (sequence). I want to shuffle integers 1-4 then apply the shuffled pattern in the table to 1-4, 5-8, 9-12, 13-16. So:
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
with a 4 item shuffling pattern of 4,2,3,1 would become:
{ 4, 2, 3, 1, 8, 6, 7, 5, 12, 10, 11, 9, 16, 14, 15, 13 }
The code here is from context and includes the "rising edge" input I am using to reshuffle. If you look at the test pic below you can see that yes, it shuffles each section in place, but it reshuffles each section -- I want the shuffled pattern to repeat.
t = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
range = 4
local function ShuffleInPlace(t)
for i = #t, 2, -1 do
local j = math.random(1, range)
local k = (math.floor(i/(range+.001)))*range + j
t[i], t[j] = t[j], t[i]
end
end
-- initialize new table for shuffling
if s == nil then s = {} end
-- use gate rising edge to shuffle
if prev == nil then prev = 0 end
if gate > 0 and prev <= 0 then
s = t
ShuffleInPlace(s)
end
prev = gate
Test pic:
LMD, thank you, your helpful reply is uncovering a solution (by creating the shuffled "pattern" sequence first, outside the iterator). (Still some issues with the first value I'm working out. And I might be looking at some biproducts of the not-so-great math.random function, but that's another story). I'm a novice so any suggestions are appreciated!
-- range input is 0 to 1
seqRange = math.floor(range*(#t*.99))
local function ShuffleRange(x)
if rdm == nil then rdm = {} end
for m = 1, x do rdm[m] = m end
for m = #rdm, 2, -1 do
local j = math.random(m)
rdm[m], rdm[j] = rdm[j], rdm[m]
return rdm[m]
end
end
local function ShuffleInPlace(t)
y = ShuffleRange(seqRange)
for i = #t, 2, -1 do
local j = (math.floor(i/(seqRange*1.001)))*seqRange + y
t[i], t[j] = t[j], t[i]
end
end
Here's how I would do it, implementing the simple approach of first generating a series of swaps and then applying that to the sublists of length n:
math.randomseed(os.time()) -- seed the random
local t = {}; for i = 1, 16 do t[i] = i end -- build table
local n = 4 -- size of subtables
local swaps = {} -- list of swaps of offsets (0-based)
for i = 0, n - 1 do
-- Insert swap into list of swaps to carry out
local j = math.random(i, n - 1)
table.insert(swaps, {i, j})
end
-- Apply swaps to every subtable from i to i + n
for i = 1, #t, n do
for _, swap in ipairs(swaps) do
-- Swap: First add offsets swap[1] & swap[2] respectively
local a, b = i + swap[1], i + swap[2]
t[a], t[b] = t[b], t[a]
end
end
print(table.concat(t, ", "))
Example output: 4, 2, 1, 3, 8, 6, 5, 7, 12, 10, 9, 11, 16, 14, 13, 15
I need a little help here
Let's suppose I have a table with numbers.
tbl = {'item1' = 6, 'item2' = 1, 'item3' = 6, 'item4' = 3, 'item5' = 2, 'item5' = 3}
I wanna put all repeated numbers in the same table (with key and value) like this:
repeated = {'item1' = 6, 'item3' = 6, 'item4' = 3, 'item5' = 3}
and creat a new one with the "not repeated" numbers:
notrepeated = {'item2' = 1, 'item5' = 2}
Can someone help? Thank you so much.
-- Count the items for each number
local itemsByNum = {}
for item, num in pairs(tbl) do
itemsByNum[num] = (itemsByNum[num] or 0) + 1
end
-- Now move objects to the respective tables
local rep, noRep = {}, {} -- can't use "repeat" as that's a Lua keyword
for item, num in pairs(tbl) do
if itemsByNum[num] > 1 then -- repeated at least once
rep[item] = num
else -- unique number
norep[item] = num
end
end
I am trying to loop through every other element in an table but I cannot find a way to do so.
Any help is appreciated.
Thank you.
It depends what kind of table you're working with. If you have an array-like table, you can use a simple for-loop :
local t = {1, 2, 3, 4, 5, 6, 7, 8}
-- start at 1, loop until i > the length of t, increment i by 2 every loop
for i = 1, #t, 2 do
local val = t[i]
print(val) -- will print out : 1, 3, 5, 7
end
But if you have a dictionary-like table, you will need something to track which key to skip. You could use a simple boolean to keep track, but be aware that there is no guaranteed order of a dictionary-like table.
local t = {
a = 1,
b = 2,
c = 3,
d = 4,
}
local shouldPrint = true
for k, v in pairs(t) do
-- only print the value when it's true
if shouldPrint then
print(k, v) -- will probably print a, 1 and c, 3
end
-- swap shouldPrint's value every loop
shouldPrint = !shouldPrint
end
Maybe try this
local count = 0
for i = 1 , #table/2 do
table[count + i].value = value
count = count + 1
end
Add to the count as you go down
x = {1, 2, 3}
y = {4, 5, 6}
z = x + y
I have two tables x and y and just want to create a third one which is just the sum of elements in them. I use the above LUA code in an effort but this gives error input:3: attempt to perform arithmetic on a table value (global 'x')...
Like, I want the result z = {5, 7, 9}
Please suggest functions that will be helpful, or please help me form such a function in LUA.
Thanks
Yes, iterate and check with table.concat()
do...
x = {1, 2, 3}
y = {4, 5, 6}
z = {}
-- First check same table length and if so then add sums to z table
if #x==#y then
for i=1,#x do
z[i]=x[i]+y[i]
end
end
print(table.concat(z,' '))
-- puts out: 5 7 9
...end
You cannot add tables in Lua unless you implement the __add metamethod.
For an element wise sum of two sequences simply do this:
function sumElements(t1,t2)
local result = {}
for i = 1, math.min(#t1, #t2) do
result[i] = t1[i] + t2[i]
end
return result
end
of course you should verify your inputs and think about how you want to deal with mismatching table sizes. Let's say t1 has 3 elements and t2 has 5, will you just have 3 result values or will you add 0 to the remaining 2?
I am trying to sort a table 'array' that contains tables with two keys called 'pt' and 'angle'. I want to sort the 'array' elements regarding their 'angle' value. To my understanding of table.sort this code snippet should do the trick:
local array = {}
-- Some code that calls
-- table.insert(array, {pt = somePt, angle = someAngle})
-- multiple times
local sorted_table = table.sort(array, function(a,b) return a.angle < b.angle end)
However, sorted_table is always nil. Am I doing something wrong here?
table.sort sorts the array part of a table in place. It does not return a new array. If you need to keep the original, you first need to copy to a temporary array.
So, try something like this:
table.sort(array,function(a,b) return a.angle < b.angle end)
table.sort sorts the table in place; that is, it changes the table that you give it and doesn't return a new one.
If you want a sorted copy, you'd first have to make a copy of the table yourself, then sort it.
This could look like this:
local function sorted_copy(tab, func)
local tab = {table.unpack(tab)}
table.sort(tab, func)
return tab
end
That will create a copy of the table (at least the numeric indices up to some random border) and sort it.
there is no secret, there is an algorithm for this sorting, which has been used many times:
function quicksort(t, sortname, start, endi)
start, endi = start or 1, endi or #t
sortname = sortname or 1
if(endi - start < 1) then return t end
local pivot = start
for i = start + 1, endi do
if t[i][sortname] <= t[pivot][sortname] then
local temp = t[pivot + 1]
t[pivot + 1] = t[pivot]
if(i == pivot + 1) then
t[pivot] = temp
else
t[pivot] = t[i]
t[i] = temp
end
pivot = pivot + 1
end
end
t = quicksort(t, sortname, start, pivot - 1)
return quicksort(t, sortname, pivot + 1, endi)
end
local array = {}
table.insert(array, {pt = 1, angle = 2})
table.insert(array, {pt = 4, angle = 9})
table.insert(array, {pt = 1, angle = 5})
table.insert(array, {pt = 2, angle = 7})
table.insert(array, {pt = 2, angle = 1})
table.insert(array, {pt = 5, angle = 2})
local s_t = quicksort(array, "angle")
for k,v in pairs(s_t) do
print(k, "v=", v.pt, v.angle)
end
Output:
1 v= 2 1
2 v= 5 2
3 v= 1 2
4 v= 1 5
5 v= 2 7
6 v= 4 9