字符串拼接 StringBuilder

函数参照c#的StringBuilder

  1 require "utf8Ext"
  2 
  3 StringBuilder = StringBuilder or {}
  4 
  5 function StringBuilder.new()
  6     local inst = {}
  7     
  8     local charBuff = {}
  9     local len = 0
 10     
 11     function inst:count()
 12         return len
 13     end
 14     
 15     function inst:get(index)
 16         assert(index >= 1 and index <= len, "get: out of range")
 17         return charBuff[index]
 18     end
 19     
 20     function inst:clear()
 21         for i=1,len do
 22             charBuff[i] = nil
 23         end
 24         len = 0
 25         return self
 26     end
 27     
 28     --function inst:capacity() end
 29     
 30     function inst:copyTo(dst)
 31         error("todo")
 32     end
 33     
 34     function inst:append(value, index, count)
 35         local vType = type(value)
 36         if "string" == vType then
 37             local tb, ct = string.utf8CharArray(value, index, count, charBuff, len+1)
 38             len = len + ct
 39         elseif "number" == vType then
 40             local str = tostring(value)
 41             local strLen = #str
 42             for i=1,strLen do
 43                 charBuff[len+i] = str:sub(i, i)
 44             end
 45             len = len + strLen
 46         else
 47             error("append: invalid value type: " .. vType)
 48         end
 49         return self
 50     end
 51     
 52     function inst:insert(index, value, vIndex, count)
 53         assert(index >= 1 and index <= len, "insert: out of range")
 54         
 55         local vType = type(value)
 56         if "string" == vType then
 57             if nil == count then count = string.utf8StringLen(value) end
 58             
 59             for i=len,index,-1 do --往后移n个
 60                 charBuff[i+count] = charBuff[i]
 61             end
 62             string.utf8CharArray(value, vIndex, count, charBuff, index)
 63             len = len + count
 64         elseif "number" == vType then
 65             for i=len,index,-1 do --往后移1个
 66                 charBuff[i+1] = charBuff[i]
 67             end
 68             charBuff[index] = value
 69             len = len + 1
 70         else
 71             error("insert: invalid value type: " .. vType)
 72         end
 73         return self
 74     end
 75     
 76     function inst:replace(oldValue, newValue, index, count)
 77         error("todo")
 78         --[[
 79         local vType = type(value)
 80         if "string" == vType then
 81         else
 82             error("replace: invalid value type: " .. vType)
 83         end
 84         return self
 85         ]]
 86     end
 87     
 88     function inst:remove(index, count)
 89         assert(index >= 1 and index <= len, "remove: out of range")
 90         local index2 = index + count
 91         
 92         if index2 > len then --删除尾部的n个元素
 93             for i=index,len do
 94                 charBuff[i] = nil
 95             end
 96             len = index - 1
 97         else --删除中间或开头的n个元素
 98             local j = index
 99             for i=index2,len do --尾部的元素往前填充
100                 charBuff[j] =charBuff[i]
101                 j = j + 1
102             end
103             for i=j,len do
104                 charBuff[i] = nil
105             end
106             len = len - count
107         end
108         return self
109     end
110     
111     function inst:__tostring()
112         if 0 == len then return "" end
113         return table.concat(charBuff)
114     end
115     
116     function inst:__len()
117         return len
118     end
119     
120     function inst:__index(k)
121         assert("number" == type(k), "k not number: " .. k)
122         return self:get(k)
123     end
124     
125     function inst:__newindex(k, v)
126         assert("number" == type(k), "k not number: " .. k)
127         assert("string" == type(v) and 1 == string.utf8StringLen(v), "v not utf8 char: " .. v .. ":" .. type(v))
128         charBuff[k] = v
129     end
130     
131     setmetatable(inst, inst)
132     return inst
133 end
134 
135 function StringBuilder.__call()
136     return StringBuilder.new()
137 end
138 setmetatable(StringBuilder, StringBuilder)

 

测试代码:

 1 local function Test1()
 2     local sb = StringBuilder()
 3     assert(0 == sb:count(), "count error")
 4     
 5     sb:append("中文")
 6     assert(2 == sb:count(), "append error")
 7     assert("" == sb[1], "append error")
 8     assert("" == sb[2], "append error")
 9     assert("中文" == tostring(sb))
10     
11     sb:append(12)
12     assert(4 == sb:count(), "append error")
13     assert("" == sb[1], "append error")
14     assert("" == sb[2], "append error")
15     assert("1" == sb[3], "append error")
16     assert("2" == sb[4], "append error")
17     assert("中文12" == tostring(sb))
18     
19     sb[4] = "3"
20     assert(4 == sb:count(), "append error")
21     assert("" == sb[1], "append error")
22     assert("" == sb[2], "append error")
23     assert("1" == sb[3], "append error")
24     assert("3" == sb[4], "append error")
25     assert("中文13" == tostring(sb))
26     
27     --sb[4] = 3 --error
28     --sb[4] = "aa"
29     sb:insert(1, "汉语")
30     assert(6 == sb:count(), "insert error")
31     assert("汉语中文13" == tostring(sb))
32     
33     sb:insert(5, 00)
34     assert("汉语中文013" == tostring(sb))
35     
36     sb:insert(3, "。,!")
37     assert(10 == sb:count(), "insert error")
38     assert("汉语。,!中文013" == tostring(sb))
39     
40     sb:remove(2, 4)
41     assert(6 == sb:count(), "remove error")
42     assert("汉中文013" == tostring(sb))
43     
44     sb:remove(5, 2)
45     assert(4 == sb:count(), "remove error")
46     assert("汉中文0" == tostring(sb))
47     
48     sb:remove(4, 10)
49     assert(3 == sb:count(), "remove error")
50     assert("汉中文" == tostring(sb))
51     
52     sb:remove(1, 2)
53     assert(1 == sb:count(), "remove error")
54     assert("" == tostring(sb))
55 end
56 
57 Test1()

 

posted @ 2021-11-12 01:03  yanghui01  阅读(99)  评论(0编辑  收藏  举报