**This is an old revision of the document!**

Transforms(变换)

transforms(变换)库提供了一套用于带索引表的实用工具。此运行库提供了高度可复用的特殊迭代器,这些迭代器是textsh命令解析的核心。

Transforms(变换) API

  • Transforms工作于序列之上

    所有的transform方法都预期在序列上迭代,参见https://www.lua.org/manual/5.2/manual.html#3.4.6

  • first 与 last

    此API所有的 firstlast 参数均与string方法(例如string.sub)中的 firstlast 参数工作方式一致。因此可以接收负值,负值为从后向前数。first(当选择时)默认相当于 1,而 last 默认相当于 -1。

  • 判断函数(predicate,谓词)

    译者注:此处的predicate通用的译名是“谓词”,指根据条件返回布尔值的函数。但译者认为这是相当糟糕的译名,不利于理解。因此译为“判断函数”。
    所有接收判断函数的transform方法均使用以下定义:

    • predicate(element: value, index: number, tbl: table): number, number

      此判断函数会在 tbl的每个索引上依次调用。 elementtbl[index] 中的值。通常而言,判断函数将会忽略 indextbl,仅处理element。但一些判断函数可能会需要检查tbl中在index之前或之后的值。(重要!)应注意,传递给判断函数的tbl实际上只是传递给transform api的原始表的一个视图(view)。此处的视图(view)不是原生的序列,而是只会返回tbl中 [first, last] 范围内的值。

      换言之,判断函数处理一个“元素组”,并返回代表满足的条件的值。

      • 元素组

        “元素组”一词代指下列之一:

        A)传递给判断函数的单个element。与tbl[index]的值为同一个。

        或者

        B)tbl中自index起的元素序列。判断函数可能会从index处开始迭代,数量为其需要检查的元素数,直到 #tbl 为止。

      • 返回值

        返回值的可能情况:
        参数1:若为falsenil,代表元素组不满足判断函数的条件。
        若为index,代表满足条件。函数应当直接返回给定函数的索引号,也就是元素组的起始元素索引号。
        参数2:满足判断函数的元素组大小,或nil
        一些tranform方法可能会将第二个参数指定为可选,例如transforms.first()

        一些transform方法可能会指定其他可用的判断数据类型,例如表或字符串。这些判断函数的用法特定于对应的方法,且在此处详细列出的方法中定义。

方法

  • transforms.sub(tbl: table, first: number, last: number or nil): table

    string.sub 作用类似,返回tblfirstlast的子表。

  • transforms.first(tbl: table, predicate: function or table, first: number or nil, last: number or nil): number, number

    返回tbl中(范围在firstlast索引之间,包含首尾)满足predicate的首个元素的索引。第二个返回值为最后一个连续匹配的元素索引。一般而言会返回两个同样的值,即匹配的连续元素为1个。predicate可以返回第二个返回值(可选),代表匹配的连续元素序列长度。

    predicate为表时,transforms.first()将会返回tbl中首个满足条件的子表的首尾索引值,这种情况下的匹配指匹配predicate表中的任一元素。

    样例:

snippet.lua
local tx = require("transforms")
print( tx.first ( { 1, 1, 3, 2, 4, 7 }, function(e, i, tbl)
  local evens = 0
  for i=i,#tbl do
    if tbl[i] % 2 == 0 then
      evens = evens + 1
    else
      break
    end
  end
  return evens > 0, evens
end))

输出:

4  5
snippet.lua
local tx = require("transforms")
print( tx.first ( { 1, 1, 3, 2, 4, 7 }, { {1, 2}, {3, 2, 4} }) )

输出

3  5
  • transforms.partition(tbl: table, partioner: function, first: number or nil, last: number or nil): table of tables

    返回一个子表的列表,子表来自tbl,由partioner生成,范围为从firstlastpartioner为判断函数,定义见前文。

    传递给partitionerindex参数将会跳过范围,即此参数会增加nn即为分区大小。
    此方法的partitioner判断函数必须同时返回匹配的元素组的开始与结束索引。请再次参见前文的predicate相关信息。

  • transforms.begins(tbl: table, sub: table, first: number or nil, last: number or nil)

    tblfirstlast的子表完全组成了sub(自首个元素对齐),则返回truefirstlast元素可以正确处理负数。上面的表达也就是说:
    v[1] == tbl[first + 0]

    v[2] == tbl[first + 1]

    v[#v] == tbl[first + #v - 1]

    此处的first + #v - 1tbl[first, last]范围内。.

  • transforms.foreach(tbl: table, adapter: function, first: number or nil, last: number or nil)

    返回tbl中从firstlast的每个元素的修改版本。若adapter的结果出现nil则会被忽略,不会被加入结果。
    adapter函数遵循判断函数的格式,除了返回值处理方面

    • Adapter函数返回值

      简单的情况是返回单个值,例如tx.foreach({'a', 'b', 'c'}, string.upper)将会返回{'A', 'B', 'C'}
      adapter函数可以通过返回nil来跳过某个值。例如,tx.foreach({'1', 'foobar', '2'}, function(n) return tonumber(n) end)将会返回{1, 2}

      adapter函数可以返回第二个值,此值会被用于序号(返回结果键值)。例如tx.foreach({'1','foobar','3'},function(n,i) return tonumber(n), tostring(i) end)将会返回{["1"]=1, ["3"]=3}

目录