Forum

> > CS2D > Scripts > Table within a table
ForenübersichtCS2D-Übersicht Scripts-ÜbersichtEinloggen, um zu antworten

Englisch Table within a table

6 Antworten
Zum Anfang Vorherige 1 Nächste Zum Anfang

alt Table within a table

Quattro
GAME BANNED Off Offline

Zitieren
Can someone explain this test? I always use the array function to make a table and it works fine. But for some reason when I make tables within a table, all the tables are treated as one:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function array(size, value)
	local array = {}
	for i = 1, size do
		array[i] = value
	end
	return array
end

test = array(5, array(5, 0))

test[1][1] = test[1][1] + 10
test[1][2] = test[1][2] + 10

print('Changed table:')
print(test[1][1])
print(test[1][2])

print('Unchanged table:')
print(test[2][1])
print(test[2][2])

The expected result:

Changed table:
10
10
Unchanged table:
0
0

Actual result:
Changed table:
10
10
Unchanged table:
10
10

alt Re: Table within a table

TrialAndError
User Off Offline

Zitieren
Because the parameter "value" in the function array receives the same table and assigns the same table to every element.

You may think that the "array(5,0)" gets called seperately for every element but that's not the case.

1
2
3
4
5
6
7
8
function array(size, value)
     local out = {}
     for i = 1, size do
          --value is the same for every element
          out[i] = value
     end
     return out
end

the function array gets called twice:

-once for creating an array with 5 elements
-once for assigning the "array(5,0)" to every element within the table.


The code below is the behaviour you're looking for. Where every element inside "array2d" function gets assigned seperate memory address instead of all sharing one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function array(size, value)
     local out = {}
     for i = 1, size do
          out[i] = value
     end
     return out
end

function array2d(outer_size, inner_size, value)
    local out = {}
    for i = 1, outer_size do
        out[i] = array(inner_size, value)
    end
    return out
end
1× editiert, zuletzt 05.08.19 16:34:04

alt Re: Table within a table

Quattro
GAME BANNED Off Offline

Zitieren
@user TrialAndError:
It's easy without creating functions:
1
2
3
4
5
6
for i = 1, 100 do
	array2D[i] = {}
	for i2 = 1, 100 do
		array2D[i][i2] = 0
	end
end

I just don't understand why does it share the memory instead of creating separate tables? I thought they should be different functions with different local variables

alt Re: Table within a table

TrialAndError
User Off Offline

Zitieren
Yeah, you could also do it like that, but the code would get longer the more table you add.

Okay, I'll try to explain how it shares.

So a table passed onto a function is always a reference (shallow copy).

1
2
3
4
5
6
7
8
9
--a function that expects a table
function func(tbl) end

--when passing a table into the function, the table isn't passed,
--but the memory address of where the table is:

--this will create a table somewhere in memory and pass the address to the function
func({1,2,3})
--what the function gets is something like (0x1ac1230)

Let's say we pass in the table: {0, 0, 0, 0, 0} (same as array(5,0)) as the value for the array function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
function array(size, value)
	--the "value" parameter gets the value passed
	--in this case {0, 0, 0, 0, 0}
	--thus it will be the same as defining and initializing it here:
	--local value = {0, 0, 0, 0, 0}

	local out = {}
	
	
	for i = 1, size do
		--goes through each element and assign the value for them.
		--if the value happens to be a table, then the memory address of "value"
		-- is passed onto it which will be the same for every element because it's 
		out[i] = value
	end

	return out
end

--step for step:

array(5, array(5, 0))
-- 1. call the array function and pass on the arguments (first call to "array")
-- 2. when it gets to the "value" parameter, it will call array(5,0)
-- 3. array(5,0) gets called -> returns {0, 0, 0, 0, 0} (second call to "array")
-- 4. the value parameter gets assigned {0, 0, 0, 0, 0} somewhere in memory, 
--let's say at memory (0x1ac1230).
-- 5. create a table to return (let's call it "out")
-- 6. loop through "size" amount of times
-- 7. for each element; point the element to the memory address of "value".
-- 8 return the table

--Total calls to "array" - 2
--Total created tables - 2

--array(5, array(5,0)) would be the same as:
local inner_array = array(5, 0)
array(5, inner_array)

--as you can see inner_array is passed onto array function as a reference or shallow copied 
--thus all the elements would share the same memory address as inner_array

alt Re: Table within a table

Gaios
Reviewer Off Offline

Zitieren
The
value
parameter in
function array(size, value)
will be the same for all the sub-tables, because of you send the same table memory address to the function and execute the function's code.

alt Re: Table within a table

Mami Tomoe
User Off Offline

Zitieren
Untested but wouldn't this work?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function get_new_table(inner_value)
	return { inner_value }
end

function get_new_array(size, init_value, inner_value)
	if size <= 0 then return end
	
	local t, tbl
	
	if type(init_value) == 'table' and next(init_value) == nil and inner_value then
		t = true
	end
	
	for i = 1, size do
		if t then
			tbl[i] = get_new_table(inner_value)
		else
			tbl[i] = init_value
		end
	end
end


myArray = get_new_array(10, { }, 0)
Zum Anfang Vorherige 1 Nächste Zum Anfang
Einloggen, um zu antworten Scripts-ÜbersichtCS2D-ÜbersichtForenübersicht