|
14 | 14 | -- with this program (see COPYING). If not, see <https://www.gnu.org/licenses/>. |
15 | 15 | -- |
16 | 16 |
|
17 | | --- module to convert array tables into key-value tables |
18 | | -local M = {} |
| 17 | +-- Module with helpers for table manipulations. |
| 18 | +local tabular = {} |
19 | 19 |
|
20 | | --- convert a table with indexed rows into a table with named rows. e.g. |
| 20 | +-- Convert a table with indexed rows into a table with named rows. e.g. |
21 | 21 | -- {"foo", 999} -> {name = "foo", cycles = 999} with keys described by md |
22 | | -local function expand_row(metadata, row) |
| 22 | +function tabular.expand_row(metadata, row) |
23 | 23 | local expanded_row = {} |
24 | 24 | for key, val in ipairs(metadata) do |
25 | 25 | expanded_row[val] = row[key] |
26 | 26 | end |
27 | 27 | return expanded_row |
28 | 28 | end |
29 | 29 |
|
30 | | --- apply `expand_row` for each row of `t`. e.g. |
| 30 | +-- Apply `expand_row` for each row of `t`. e.g. |
31 | 31 | -- {{ "foo", 999 }} -> {{name = "foo", cycles = 999}} with keys described by md |
32 | | -M.expand = function(metadata, t) |
| 32 | +function tabular.expand(metadata, t) |
33 | 33 | local expanded_t = {} |
34 | 34 | for _, row in ipairs(t) do |
35 | | - expanded_t[#expanded_t + 1] = expand_row(metadata, row) |
| 35 | + expanded_t[#expanded_t + 1] = tabular.expand_row(metadata, row) |
36 | 36 | end |
37 | 37 | return expanded_t |
38 | 38 | end |
39 | 39 |
|
40 | | -function M.clear(t) |
| 40 | +-- Clear all key-value pairs from table `t`. |
| 41 | +function tabular.clear(t) |
41 | 42 | for k in pairs(t) do |
42 | 43 | t[k] = nil |
43 | 44 | end |
44 | 45 | end |
45 | 46 |
|
46 | | -function M.append(t, elems) |
| 47 | +-- Append all elements from `elems` to the end of table `t`. |
| 48 | +function tabular.append(t, elems) |
47 | 49 | local n = #t |
48 | 50 | for i = 1, #elems do |
49 | 51 | t[n + i] = elems[i] |
50 | 52 | end |
51 | 53 | end |
52 | 54 |
|
53 | | -return M |
| 55 | +local function deep_traverse_iter(t, path) |
| 56 | + path = path or {} |
| 57 | + for k, v in pairs(t) do |
| 58 | + local current_path = {} |
| 59 | + for i = 1, #path do |
| 60 | + current_path[i] = path[i] |
| 61 | + end |
| 62 | + current_path[#current_path + 1] = k |
| 63 | + if type(v) == "table" then |
| 64 | + deep_traverse_iter(v, current_path) |
| 65 | + else |
| 66 | + coroutine.yield(current_path, k, v) |
| 67 | + end |
| 68 | + end |
| 69 | +end |
| 70 | + |
| 71 | +-- Iterator that recursively traverses all key-value pairs in table `t`, |
| 72 | +-- yielding the path to each value, its key, and the value itself. |
| 73 | +function tabular.deep_traverse(t) |
| 74 | + return coroutine.wrap(function() |
| 75 | + deep_traverse_iter(t) |
| 76 | + end) |
| 77 | +end |
| 78 | + |
| 79 | +-- Recursively copy a table `t` and all its subtables. |
| 80 | +function tabular.deep_copy(t) |
| 81 | + local copy = {} |
| 82 | + for k, v in pairs(t) do |
| 83 | + if type(v) == "table" then |
| 84 | + copy[k] = tabular.deep_copy(v) |
| 85 | + else |
| 86 | + copy[k] = v |
| 87 | + end |
| 88 | + end |
| 89 | + return copy |
| 90 | +end |
| 91 | + |
| 92 | +return tabular |
0 commit comments