-
Notifications
You must be signed in to change notification settings - Fork 191
Table flattening
SelectricSimian edited this page Feb 21, 2013
·
1 revision
This function "flattens" a table, removing all nesting structure. For example,
flatten {
1
2
{
{
3
4
}
5
}
{
{
6
}
{
{
7
}
}
}
}
returns
{
1
2
3
4
5
6
7
}
_insert_many = (...)=> for val in *{...} do self[#self + 1] = val
_flatten = =>
switch type self
when 'table'
result = {}
for v in *self do _insert_many result, _flatten v
unpack result
else
self
export flatten = (...)-> {_flatten ...}
flatten
returns a copy of the table parameter, and is guaranteed not to modify its input.
For the sake of efficiency and simplicity, flatten
completely ignores all non-integer keys. For example,
flatten {
1
{2}
{
a: 'b'
c: 'd'
{
3
{4}
}
}
{
5
{6}
}
}
returns
{
1
2
3
4
5
6
}
For tasks which require the data held in, for example, string keys, different approaches may be used. Under certain circumstances, one may want not to flatten any non-sequence table, or any of its sub-tables:
_insert_many = (...)=> for val in *{...} do self[#self + 1] = val
-- moon.fold doesn't quite seem to work...
fold = nil
do
_fold = (fn, a, b, ...)-> if b then _fold fn, fn(a, b), ... else a
fold = (fn)=> _fold fn, unpack self
_flatten_direct_sequences = =>
switch type self
when 'table'
if #self == moon.fold [1 for k in pairs self], (a, b)-> a + b
result = {}
for v in *self do _insert_many result, _flatten v
unpack result
else
self
else
self
export flatten_direct_sequences = (...)-> {_flatten_direct_sequences ...}
example:
flatten_direct_sequences {
1
{2}
{
a: 'b'
c: 'd'
{
3
{4}
}
}
{
5
{6}
}
}
returns
{
1
2
{
a: 'b'
c: 'd'
{
3
{4}
}
}
5
6
}
Other times, it may be desirable not to flatten non-sequence tables, but to flatten all sub-tables of those tables:
_insert_many = (...)=> for val in *{...} do self[#self + 1] = val
-- moon.fold doesn't quite seem to work...
fold = nil
do
_fold = (fn, a, b, ...)-> if b then _fold fn, fn(a, b), ... else a
fold = (fn)=> _fold fn, unpack self
_flatten_all_sequences = =>
switch type self
when 'table'
if #self == moon.fold [1 for k in pairs self], (a, b)-> a + b
result = {}
for v in *self do _insert_many result, _flatten v
unpack result
else
{k, flatten_all_sequences v for k, v in pairs self}
else
self
export flatten_all_sequences = (...)-> {_flatten_all_sequences ...}
example:
flatten_all_sequences {
1
{2}
{
a: 'b'
c: 'd'
{
3
{4}
}
}
{
5
{6}
}
}
returns
{
1
2
{
a: 'b'
c: 'd'
{
3
4
}
}
5
6
}