Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

946
LINES

< > BotCompany Repo | #157 // table-utils.lua (luanucleo)

Lua code

1  
--------------------------------------------------------------------------------
2  
--- Small table utilities
3  
-- @module lua-nucleo.table-utils
4  
-- This file is a part of lua-nucleo library
5  
-- @copyright lua-nucleo authors (see file `COPYRIGHT` for the license)
6  
--------------------------------------------------------------------------------
7  
8  
local setmetatable, error, pairs, ipairs, tostring, select, type, assert
9  
    = setmetatable, error, pairs, ipairs, tostring, select, type, assert
10  
11  
local rawget = rawget
12  
13  
local table_insert, table_remove = table.insert, table.remove
14  
15  
local math_min, math_max = math.min, math.max
16  
17  
--------------------------------------------------------------------------------
18  
19  
local arguments,
20  
      optional_arguments,
21  
      method_arguments
22  
      = import 'lua-nucleo/args.lua'
23  
      {
24  
        'arguments',
25  
        'optional_arguments',
26  
        'method_arguments'
27  
      }
28  
29  
local is_number,
30  
      is_table
31  
      = import 'lua-nucleo/type.lua'
32  
      {
33  
        'is_number',
34  
        'is_table'
35  
      }
36  
37  
local assert_is_table
38  
      = import 'lua-nucleo/typeassert.lua'
39  
      {
40  
        'assert_is_table'
41  
      }
42  
43  
--------------------------------------------------------------------------------
44  
45  
-- Warning: it is possible to corrupt this with rawset and debug.setmetatable.
46  
local empty_table = setmetatable(
47  
    { },
48  
    {
49  
      __newindex = function(t, k, v)
50  
        error("attempted to change the empty table", 2)
51  
      end;
52  
53  
      __metatable = "empty_table";
54  
    }
55  
  )
56  
57  
local function toverride_many(t, s, ...)
58  
  if s then
59  
    for k, v in pairs(s) do
60  
      t[k] = v
61  
    end
62  
    -- Recursion is usually faster than calling select()
63  
    return toverride_many(t, ...)
64  
  end
65  
66  
  return t
67  
end
68  
69  
local function tappend_many(t, s, ...)
70  
  if s then
71  
    for k, v in pairs(s) do
72  
      if t[k] == nil then
73  
        t[k] = v
74  
      else
75  
        error("attempted to override table key `" .. tostring(k) .. "'", 2)
76  
      end
77  
    end
78  
79  
    -- Recursion is usually faster than calling select()
80  
    return tappend_many(t, ...)
81  
  end
82  
83  
  return t
84  
end
85  
86  
local function tijoin_many(t, s, ...)
87  
  if s then
88  
    -- Note: can't use ipairs() since we want to support tijoin_many(t, t)
89  
    for i = 1, #s do
90  
      t[#t + 1] = s[i]
91  
    end
92  
93  
    -- Recursion is usually faster than calling select()
94  
    return tijoin_many(t, ...)
95  
  end
96  
97  
  return t
98  
end
99  
100  
-- Keys are ordered in undetermined order
101  
local tkeys = function(t)
102  
  local r = { }
103  
104  
  for k, v in pairs(t) do
105  
    r[#r + 1] = k
106  
  end
107  
108  
  return r
109  
end
110  
111  
-- Values are ordered in undetermined order
112  
local tvalues = function(t)
113  
  local r = { }
114  
115  
  for k, v in pairs(t) do
116  
    r[#r + 1] = v
117  
  end
118  
119  
  return r
120  
end
121  
122  
-- Keys and values are ordered in undetermined order
123  
local tkeysvalues = function(t)
124  
  local keys, values = { }, { }
125  
126  
  for k, v in pairs(t) do
127  
    keys[#keys + 1] = k
128  
    values[#values + 1] = v
129  
  end
130  
131  
  return keys, values
132  
end
133  
134  
-- If table contains multiple keys with the same value,
135  
-- only one key is stored in the result, picked in undetermined way.
136  
local tflip = function(t)
137  
  local r = { }
138  
139  
  for k, v in pairs(t) do
140  
    r[v] = k
141  
  end
142  
143  
  return r
144  
end
145  
146  
-- If table contains multiple keys with the same value,
147  
-- only one key is stored in the result, picked in undetermined way.
148  
local tflip_inplace = function(t)
149  
  for k, v in pairs(t) do
150  
    t[v] = k
151  
  end
152  
153  
  return t
154  
end
155  
156  
-- If table contains multiple keys with the same value,
157  
-- only the last such key (highest one) is stored in the result.
158  
local tiflip = function(t)
159  
  local r = { }
160  
161  
  for i = 1, #t do
162  
    r[t[i]] = i
163  
  end
164  
165  
  return r
166  
end
167  
168  
local tset = function(t)
169  
  local r = { }
170  
171  
  for k, v in pairs(t) do
172  
    r[v] = true
173  
  end
174  
175  
  return r
176  
end
177  
178  
local tiset = function(t)
179  
  local r = { }
180  
181  
  for i = 1, #t do
182  
    r[t[i]] = true
183  
  end
184  
185  
  return r
186  
end
187  
188  
local function tiinsert_args(t, a, ...)
189  
  if a ~= nil then
190  
    t[#t + 1] = a
191  
    -- Recursion is usually faster than calling select() in a loop.
192  
    return tiinsert_args(t, ...)
193  
  end
194  
195  
  return t
196  
end
197  
198  
local timap_inplace = function(fn, t, ...)
199  
  for i = 1, #t do
200  
    t[i] = fn(t[i], ...)
201  
  end
202  
203  
  return t
204  
end
205  
206  
local timap = function(fn, t, ...)
207  
  local r = { }
208  
  for i = 1, #t do
209  
    r[i] = fn(t[i], ...)
210  
  end
211  
  return r
212  
end
213  
214  
local timap_sliding = function(fn, t, ...)
215  
  local r = {}
216  
217  
  for i = 1, #t do
218  
    tiinsert_args(r, fn(t[i], ...))
219  
  end
220  
221  
  return r
222  
end
223  
224  
local tiwalk = function(fn, t, ...)
225  
  for i = 1, #t do
226  
    fn(t[i], ...)
227  
  end
228  
end
229  
230  
local tiwalker = function(fn)
231  
  return function(t)
232  
    for i = 1, #t do
233  
      fn(t[i])
234  
    end
235  
  end
236  
end
237  
238  
local twalk_pairs = function(fn, t)
239  
  for k, v in pairs(t) do
240  
    fn(k, v)
241  
  end
242  
end
243  
244  
local tequals = function(lhs, rhs)
245  
  for k, v in pairs(lhs) do
246  
    if v ~= rhs[k] then
247  
      return false
248  
    end
249  
  end
250  
251  
  for k, v in pairs(rhs) do
252  
    if lhs[k] == nil then
253  
      return false
254  
    end
255  
  end
256  
257  
  return true
258  
end
259  
260  
local tiunique = function(t)
261  
  return tkeys(tiflip(t))
262  
end
263  
264  
-- Deprecated, use tgenerate_1d_linear instead
265  
local tgenerate_n = function(n, generator, ...)
266  
  local r = { }
267  
  for i = 1, n do
268  
    r[i] = generator(...)
269  
  end
270  
  return r
271  
end
272  
273  
local tgenerate_1d_linear = function(n, fn, ...)
274  
  local r = { }
275  
  for i = 1, n do
276  
    r[#r + 1] = fn(i, ...)
277  
  end
278  
  return r
279  
end
280  
281  
local tgenerate_2d_linear = function(w, h, fn, ...)
282  
  local r = { }
283  
  for y = 1, h do
284  
    for x = 1, w do
285  
      r[#r + 1] = fn(x, y, ...)
286  
    end
287  
  end
288  
  return r
289  
end
290  
291  
local taccumulate = function(t, init)
292  
  local sum = init or 0
293  
  for k, v in pairs(t) do
294  
    sum = sum + v
295  
  end
296  
  return sum
297  
end
298  
299  
local tnormalize, tnormalize_inplace
300  
do
301  
  local impl = function(t, r, sum)
302  
    sum = sum or taccumulate(t)
303  
304  
    for k, v in pairs(t) do
305  
      r[k] = v / sum
306  
    end
307  
308  
    return r
309  
  end
310  
311  
  tnormalize = function(t, sum)
312  
    return impl(t, { }, sum)
313  
  end
314  
315  
  tnormalize_inplace = function(t, sum)
316  
    return impl(t, t, sum)
317  
  end
318  
end
319  
320  
local tclone
321  
do
322  
  local function impl(t, visited)
323  
    local t_type = type(t)
324  
    if t_type ~= "table" then
325  
      return t
326  
    end
327  
328  
    assert(not visited[t], "recursion detected")
329  
    visited[t] = true
330  
331  
    local r = { }
332  
    for k, v in pairs(t) do
333  
      r[impl(k, visited)] = impl(v, visited)
334  
    end
335  
336  
    visited[t] = nil
337  
338  
    return r
339  
  end
340  
341  
  tclone = function(t)
342  
    return impl(t, { })
343  
  end
344  
end
345  
346  
-- Slow
347  
local tcount_elements = function(t)
348  
  local n = 0
349  
  for _ in pairs(t) do
350  
    n = n + 1
351  
  end
352  
  return n
353  
end
354  
355  
local tremap_to_array = function(fn, t)
356  
  local r = { }
357  
  for k, v in pairs(t) do
358  
    r[#r + 1] = fn(k, v)
359  
  end
360  
  return r
361  
end
362  
363  
local tmap_values = function(fn, t, ...)
364  
  local r = { }
365  
  for k, v in pairs(t) do
366  
    r[k] = fn(v, ...)
367  
  end
368  
  return r
369  
end
370  
371  
--------------------------------------------------------------------------------
372  
373  
local torderedset = function(t)
374  
  local r = { }
375  
376  
  for i = 1, #t do
377  
    local v = t[i]
378  
379  
    -- Have to add this limitation to avoid size ambiquity.
380  
    -- If you need ordered set of numbers, use separate storage
381  
    -- for set and array parts (write make_ordered_set then).
382  
    assert(type(v) ~= "number", "can't insert number into ordered set")
383  
384  
    r[v] = i
385  
    r[i] = v
386  
  end
387  
388  
  return r
389  
end
390  
391  
-- Returns false if item already exists
392  
-- Returns true otherwise
393  
local torderedset_insert = function(t, v)
394  
  -- See torderedset() for motivation
395  
  assert(type(v) ~= "number", "can't insert number into ordered set")
396  
397  
  if not t[v] then
398  
    local i = #t + 1
399  
    t[v] = i
400  
    t[i] = v
401  
402  
    return true
403  
  end
404  
405  
  return false
406  
end
407  
408  
-- Returns false if item didn't existed
409  
-- Returns true otherwise
410  
-- Note this operation is really slow
411  
local torderedset_remove = function(t, v)
412  
  -- See torderedset() for motivation
413  
  assert(type(v) ~= "number", "can't remove number from ordered set")
414  
415  
  local pos = t[v]
416  
  if pos then
417  
    t[v] = nil
418  
    -- TODO: Do table.remove manually then to do all in a single loop.
419  
    table_remove(t, pos)
420  
    for i = pos, #t do
421  
      t[t[i]] = i -- Update changed numbers
422  
    end
423  
  end
424  
425  
  return false
426  
end
427  
428  
--------------------------------------------------------------------------------
429  
430  
-- Handles subtables (is "deep").
431  
-- Does not support recursive defaults tables
432  
-- WARNING: Uses tclone()! Do not use on tables with metatables!
433  
local twithdefaults
434  
do
435  
  twithdefaults = function(t, defaults)
436  
    for k, d in pairs(defaults) do
437  
      local v = t[k]
438  
      if v == nil then
439  
        if type(d) == "table" then
440  
          d = tclone(d)
441  
        end
442  
        t[k] = d
443  
      elseif type(v) == "table" and type(d) == "table" then
444  
        twithdefaults(v, d)
445  
      end
446  
    end
447  
448  
    return t
449  
  end
450  
end
451  
452  
--------------------------------------------------------------------------------
453  
454  
local tifilter = function(pred, t, ...)
455  
  local r = { }
456  
  for i = 1, #t do
457  
    local v = t[i]
458  
    if pred(v, ...) then
459  
      r[#r + 1] = v
460  
    end
461  
  end
462  
  return r
463  
end
464  
465  
--------------------------------------------------------------------------------
466  
467  
local tsetof = function(value, t)
468  
  local r = { }
469  
470  
  for k, v in pairs(t) do
471  
    r[v] = value
472  
  end
473  
474  
  return r
475  
end
476  
477  
--------------------------------------------------------------------------------
478  
479  
local tset_many = function(...)
480  
  local r = { }
481  
482  
  for i = 1, select("#", ...) do
483  
    for k, v in pairs((select(i, ...))) do
484  
      r[v] = true
485  
    end
486  
  end
487  
488  
  return r
489  
end
490  
491  
-- TODO: Pick a better name?
492  
local tidentityset = function(t)
493  
  local r = { }
494  
495  
  for k, v in pairs(t) do
496  
    r[v] = v
497  
  end
498  
499  
  return r
500  
end
501  
502  
--------------------------------------------------------------------------------
503  
504  
local timapofrecords = function(t, key)
505  
  local r = { }
506  
507  
  for i = 1, #t do
508  
    local v = t[i]
509  
    r[assert(v[key], "missing record key field")] = v
510  
  end
511  
512  
  return r
513  
end
514  
515  
local tivalues = function(t)
516  
  local r = { }
517  
518  
  for i = 1, #t do
519  
    r[#r + 1] = t[i]
520  
  end
521  
522  
  return r
523  
end
524  
525  
--------------------------------------------------------------------------------
526  
527  
-- NOTE: Optimized to be fast at simple value indexing.
528  
--       Slower on initialization and on table value fetching.
529  
-- WARNING: This does not protect userdata.
530  
local treadonly, treadonly_ex
531  
do
532  
  local newindex = function()
533  
    error("attempted to change read-only table")
534  
  end
535  
536  
  treadonly = function(value, callbacks, tostring_fn, disable_nil)
537  
    callbacks = callbacks or empty_table
538  
    if disable_nil == nil then
539  
      disable_nil = true
540  
    end
541  
542  
    arguments(
543  
        "table", value,
544  
        "table", callbacks
545  
      )
546  
547  
    optional_arguments(
548  
        "function", tostring_fn,
549  
        "boolean", disable_nil -- TODO: ?! Not exactly optional
550  
      )
551  
552  
    local mt =
553  
    {
554  
      __metatable = "treadonly"; -- protect metatable
555  
556  
      __index = function(t, k)
557  
        local v = rawget(value, k)
558  
        if is_table(v) then
559  
          -- TODO: Optimize
560  
          v = treadonly(v, callbacks, tostring_fn, disable_nil)
561  
        end
562  
        if v == nil then -- TODO: Try to use metatables
563  
          -- Note: __index does not support multiple return values in 5.1,
564  
          --       so we can not do call right here.
565  
          local fn = callbacks[k]
566  
          if fn then
567  
            return function(...) return fn(value, ...) end
568  
          end
569  
          if disable_nil then
570  
            error(
571  
                "attempted to read inexistant value at key " .. tostring(k),
572  
                2
573  
              )
574  
          end
575  
        end
576  
        return v
577  
      end;
578  
579  
      __newindex = newindex;
580  
    }
581  
582  
    if tostring_fn then
583  
      mt.__tostring = function() return tostring_fn(value) end
584  
    end
585  
586  
    return setmetatable({ }, mt)
587  
  end
588  
589  
  -- Changes to second return value are guaranteed to affect first one
590  
  treadonly_ex = function(value, ...)
591  
    local protected = treadonly(value, ...)
592  
    return protected, value
593  
  end
594  
end
595  
596  
local tmap_kv = function(fn, t)
597  
  local r = { }
598  
  for k, v in pairs(t) do
599  
    k, v = fn(k, v)
600  
    r[k] = v
601  
  end
602  
  return r
603  
end
604  
605  
local tmapofrecordgroups = function(t, key_name)
606  
  local r = { }
607  
  for k, v in pairs(t) do
608  
    local v = t[k]
609  
    local key = assert(v[key_name], "missing required key")
610  
    local g = r[key]
611  
    if not g then
612  
      g = { }
613  
      r[key] = g
614  
    end
615  
    g[#g + 1] = v
616  
  end
617  
618  
  return r
619  
end
620  
621  
local timapofrecordgroups = function(t, key_name)
622  
  local r = { }
623  
  for i = 1, #t do
624  
    local v = t[i]
625  
    local key = assert(v[key_name], "missing required key")
626  
    local g = r[key]
627  
    if not g then
628  
      g = { }
629  
      r[key] = g
630  
    end
631  
    g[#g + 1] = v
632  
  end
633  
634  
  return r
635  
end
636  
637  
local tilistofrecordfields = function(t, k)
638  
  local r = { }
639  
  for i = 1, #t do
640  
    local v = t[i][k]
641  
    assert(v ~= nil, "missing required key")
642  
    r[#r + 1] = v
643  
  end
644  
  return r
645  
end
646  
647  
local tipermute_inplace = function(t, n, count, random)
648  
  n = n or #t
649  
  count = count or n
650  
  random = random or math.random
651  
652  
  for i = 1, count do
653  
    local j = random(i, n)
654  
    t[i], t[j] = t[j], t[i]
655  
  end
656  
657  
  return t
658  
end
659  
660  
local tkvtorecordlist = function(t, key_name, value_name)
661  
  local result = { }
662  
  for k, v in pairs(t) do
663  
    result[#result + 1] = { [key_name] = k, [value_name] = v }
664  
  end
665  
  return result
666  
end
667  
668  
local function tgetpath(t, k, nextk, ...)
669  
  if k == nil then
670  
    return nil
671  
  end
672  
673  
  local v = t[k]
674  
  if not is_table(v) or nextk == nil then
675  
    return v
676  
  end
677  
678  
  return tgetpath(v, nextk, ...)
679  
end
680  
681  
--  tsetpath(tabl, "a", "b", "c", d)
682  
--  tabl.a.b.c[d] = val
683  
local tsetpath
684  
do
685  
  local function impl(nargs, dest, key, ...)
686  
687  
    if nargs == 0 then
688  
      return dest
689  
    end
690  
691  
    if key == nil then
692  
      error("tsetpath: nil can't be a table key")
693  
    end
694  
695  
    dest[key] = assert_is_table(
696  
        dest[key] or { },
697  
        "key `" .. tostring(key)
698  
     .. "' already exists and its value is not a table"
699  
      )
700  
701  
    return impl(nargs - 1, dest[key], ...)
702  
  end
703  
704  
  tsetpath = function(dest, ...)
705  
    local nargs = select("#", ...)
706  
    if nargs == 0 then
707  
      return dest
708  
    end
709  
710  
    return impl(nargs, dest, ...)
711  
  end
712  
end
713  
714  
local tsetpathvalue
715  
do
716  
  local function impl(nargs, value, dest, key, ...)
717  
    assert(nargs > 0)
718  
719  
    if key == nil then
720  
      error("tsetpathvalue: nil can't be a table key")
721  
    end
722  
723  
    if nargs == 1 then
724  
      dest[key] = value
725  
      return dest
726  
    end
727  
728  
    dest[key] = assert_is_table(
729  
        dest[key] or { },
730  
        "key `" .. tostring(key)
731  
     .. "' already exists and its value is not a table"
732  
      )
733  
734  
    return impl(nargs - 1, value, dest[key], ...)
735  
  end
736  
737  
  tsetpathvalue = function(value, dest, ...)
738  
    local nargs = select("#", ...)
739  
    if nargs == 0 then
740  
      return dest
741  
    end
742  
743  
    return impl(nargs, value, dest, ...)
744  
  end
745  
end
746  
747  
-- TODO: rename to tislice
748  
local tslice = function(t, start_i, end_i)
749  
  local r = { }
750  
751  
  start_i = math_max(start_i, 1)
752  
  end_i = math_min(end_i, #t)
753  
  for i = start_i, end_i do
754  
    r[i - start_i + 1] = t[i]
755  
  end
756  
757  
  return r
758  
end
759  
760  
local tarraylisttohashlist = function(t, ...)
761  
  local r = { }
762  
  local nargs = select("#", ...)
763  
764  
  for i = 1, #t do
765  
    local item = { }
766  
    for j = 1, nargs do
767  
      local hash = select(j, ...)
768  
      if hash ~= nil then -- ignore nil from arguments
769  
        item[hash] = t[i][j]
770  
      end
771  
    end
772  
    r[#r + 1] = item
773  
  end
774  
775  
  return r
776  
end
777  
778  
local tarraytohash = function(t, ...)
779  
  local r = { }
780  
  local nargs = select("#", ...)
781  
782  
  for i = 1, nargs do
783  
    local hash = select(i, ...)
784  
    if hash ~= nil then -- ignore nil from arguments
785  
      r[hash] = t[i]
786  
    end
787  
  end
788  
789  
  return r
790  
end
791  
792  
local tisempty = function(t)
793  
  return next(t) == nil
794  
end
795  
796  
local tifindvalue_nonrecursive = function(t, v)
797  
  for i = 1, #t do
798  
    if t[i] == v then
799  
      return true
800  
    end
801  
  end
802  
  return false
803  
end
804  
805  
local tkvlist2kvpairs = function(t)
806  
  local r = { }
807  
  for i = 1, #t, 2 do
808  
    local k, v = t[i], t[i+1]
809  
    if k ~= nil then
810  
      r[k] = v
811  
    end
812  
  end
813  
  return r
814  
end
815  
816  
local tfilterkeylist = function(t, f, strict)
817  
  strict = strict or false
818  
  local r = { }
819  
820  
  for i = 1, #f do
821  
    local k = f[i]
822  
    if t[k] ~= nil then
823  
      r[k] = t[k]
824  
    elseif strict then
825  
      return nil, "Field `" .. tostring(k) .. "' is absent"
826  
    end
827  
  end
828  
  return r
829  
end
830  
831  
local tkvmap_unpack = function(fn, t, ...)
832  
  local r = { }
833  
  for k, v in pairs(t) do
834  
    k, v = fn(k, ...), fn(v, ...)
835  
836  
    if k ~= nil and v ~= nil then
837  
      r[#r + 1] = k
838  
      r[#r + 1] = v
839  
    end
840  
  end
841  
  return unpack(r)
842  
end
843  
844  
local tkvlist_to_hash = function(t)
845  
  local r = { }
846  
  for i = 1, #t, 2 do
847  
    r[t[i]] = t[i + 1]
848  
  end
849  
  return r
850  
end
851  
852  
local tmerge_many = function(...)
853  
  return toverride_many({ }, ...)
854  
end
855  
856  
-- Returns true is a table is an array
857  
-- Returns false otherwise
858  
-- Note the empty table is treated as an array
859  
local tisarray = function(t)
860  
  for k, _ in pairs(t) do
861  
    if
862  
      -- Array keys should be numbers...
863  
      not is_number(k)
864  
      -- ...greater than 1...
865  
      or k < 1
866  
      -- ...in a continuous sequence...
867  
      or (k > 1 and t[k - 1] == nil)
868  
      -- ...of integers...
869  
      or k % 1 ~= 0
870  
      -- ...avoiding floating point overflow
871  
      or k == k - 1
872  
    then
873  
      return false
874  
    end
875  
  end
876  
  return true
877  
end
878  
879  
--------------------------------------------------------------------------------
880  
881  
return
882  
{
883  
  empty_table = empty_table;
884  
  toverride_many = toverride_many;
885  
  tappend_many = tappend_many;
886  
  tijoin_many = tijoin_many;
887  
  tkeys = tkeys;
888  
  tvalues = tvalues;
889  
  tkeysvalues = tkeysvalues;
890  
  tflip = tflip;
891  
  tflip_inplace = tflip_inplace;
892  
  tiflip = tiflip;
893  
  tset = tset;
894  
  tiset = tiset;
895  
  tisarray = tisarray;
896  
  tiinsert_args = tiinsert_args;
897  
  timap_inplace = timap_inplace;
898  
  timap = timap;
899  
  timap_sliding = timap_sliding;
900  
  tiwalk = tiwalk;
901  
  tiwalker = tiwalker;
902  
  tequals = tequals;
903  
  tiunique = tiunique;
904  
  tgenerate_n = tgenerate_n; -- deprecated
905  
  tgenerate_1d_linear = tgenerate_1d_linear;
906  
  tgenerate_2d_linear = tgenerate_2d_linear;
907  
  taccumulate = taccumulate;
908  
  tnormalize = tnormalize;
909  
  tnormalize_inplace = tnormalize_inplace;
910  
  tclone = tclone;
911  
  tcount_elements = tcount_elements;
912  
  tremap_to_array = tremap_to_array;
913  
  twalk_pairs = twalk_pairs;
914  
  tmap_values = tmap_values;
915  
  torderedset = torderedset;
916  
  torderedset_insert = torderedset_insert;
917  
  torderedset_remove = torderedset_remove;
918  
  twithdefaults = twithdefaults;
919  
  tifilter = tifilter;
920  
  tsetof = tsetof;
921  
  tset_many = tset_many;
922  
  tidentityset = tidentityset;
923  
  timapofrecords = timapofrecords;
924  
  tivalues = tivalues;
925  
  treadonly = treadonly;
926  
  treadonly_ex = treadonly_ex;
927  
  tmap_kv = tmap_kv;
928  
  tmapofrecordgroups = tmapofrecordgroups;
929  
  timapofrecordgroups = timapofrecordgroups;
930  
  tilistofrecordfields = tilistofrecordfields;
931  
  tipermute_inplace = tipermute_inplace;
932  
  tkvtorecordlist = tkvtorecordlist;
933  
  tgetpath = tgetpath;
934  
  tsetpath = tsetpath;
935  
  tsetpathvalue = tsetpathvalue;
936  
  tslice = tslice;
937  
  tarraylisttohashlist = tarraylisttohashlist;
938  
  tarraytohash = tarraytohash;
939  
  tkvlist2kvpairs = tkvlist2kvpairs;
940  
  tfilterkeylist = tfilterkeylist;
941  
  tisempty = tisempty;
942  
  tifindvalue_nonrecursive = tifindvalue_nonrecursive;
943  
  tkvmap_unpack = tkvmap_unpack;
944  
  tkvlist_to_hash = tkvlist_to_hash;
945  
  tmerge_many = tmerge_many;
946  
}

test run  test run with input  download  show line numbers   

Travelled to 12 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Image recognition results

Recognizer Recognition Result Visualize Recalc
#308 19795 [visualize]

Snippet ID: #157
Snippet name: table-utils.lua (luanucleo)
Eternal ID of this version: #157/1
Text MD5: 886ad3506df943b2b2a59e5315f48d1a
Author: stefan
Category:
Type: Lua code
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2014-01-13 03:45:08
Source code size: 19795 bytes / 946 lines
Pitched / IR pitched: Yes / Yes
Views / Downloads: 1016 / 289
Referenced in: [show references]