How to split a Lua table containing sub-tables
Asked Answered
F

2

6

How can I split a Lua table containing few sub-tables into two tables without changing the original table.

e.g. split tbl = {{tbl1}, {tbl2}, {tbl3}, {tbl4}} into subtbl1 = {{tbl1}, {tbl2}}, subtbl2 = {{tbl3}, {tbl4}} while keep tbl unchanged.

String has string.sub, but don't know if table has something similar. I don't think unpack works for my case, also table.remove will change the original tbl.

Adding more information for my real case:

The tbl is filled up with sub-tables at run-time and the number of sub-tables changes. I want to keep the first 2 sub-tables for something and pass the rest of the sub-tables (in one table) to a function.

Fortdefrance answered 9/1, 2015 at 16:42 Comment(2)
The second function expects a table of tables (starting at index 1)? You want tbl to contain just the first two sub-tables?Frigidarium
Yes, the second function expects a table of tables starting at index 1. But the first two sub-tables are not needed as a table. I only have to retrieve the information from the first two sub-tables.Fortdefrance
T
7

You can keep the first two sub-tables using the method lhf suggested. You could then unpack the remaining sub-tables.

local unpack = table.unpack or unpack

local t = { {1}, {2}, {3}, {4}, {5}, {6} }

local t1 = { t[1], t[2] }    -- keep the first two subtables
local t2 = { unpack(t, 3) }  -- unpack the rest into a new table

-- check that t has been split into two sub-tables leaving the original unchanged
assert(#t == 6, 't has been modified')

-- t1 contains the first two sub-tables of t
assert(#t1 == 2, 'invalid table1 length')
assert(t[1] == t1[1], 'table1 mismatch at index 1')
assert(t[2] == t1[2], 'table1 mismatch at index 2')

-- t2 contains the remaining sub-tables in t
assert(#t2 == 4, 'invalid table2 length')
assert(t[3] == t2[1], 'table2 mismatch at index 1')
assert(t[4] == t2[2], 'table2 mismatch at index 2')
assert(t[5] == t2[3], 'table2 mismatch at index 3')
assert(t[6] == t2[4], 'table2 mismatch at index 4')
Tabaret answered 9/1, 2015 at 17:35 Comment(3)
unpack supports arguments for starting and ending indices, no need for select. Just unpack(t, 3).Frigidarium
@EtanReisner Thanks for the feedback. I have updated my answer to incorporate your suggestion.Tabaret
Thank you guys! {unpack(t, 3)} is great for my case.Fortdefrance
S
2

Try this:

subtbl1 = { tbl[1], tbl[2] }
subtbl2 = { tbl[3], tbl[4] }
Sodomy answered 9/1, 2015 at 16:54 Comment(1)
Thank you, but my case is more complicated. The real case I have is that the original tbl is filled up with sub-tables at run-time. The goal is to pass the rest of the sub-tables except the first 2 to a function, and the first 2 sub-tables are used in somewhere else so the original table is not expected to be modified after it's filled up.Fortdefrance

© 2022 - 2024 — McMap. All rights reserved.