概述
在打印输出或其他地方可能需要构建有序或无序列表。本质就是构造和维护一个纯文本数组。并用格式化文本形式,输出带序号或前缀字符的多行文本。
为此我专门设计了一个类myList
,来完成这项任务。
代码
以下是myList
类的完整代码:
# ========================================================
# 名称:myList
# 类型:类
# 简介:专用于构造有序和无序列表的类
# 作者:巽星石
# Godot版本:v4.2.2.stable.official [15073afe3]
# 创建时间:2024年4月27日11:25:40
# 最后修改时间:2024年4月27日16:26:10
# ========================================================
class_name myListvar _arr:PackedStringArray# 实例化
func _init(list:PackedStringArray = []) -> void:_arr = list# ============================ 增删改查 ============================
# -------------------- 增
# 末尾添加列表项
func append(item:String) -> void:_arr.append(item)# 末尾添加列表项
func insert(pos:int,item:String) -> void:_arr.insert(pos,item)# 添加多个列表项
func append_array(items:PackedStringArray) -> void:_arr.append_array(items)# 填充指定数目的相同列表项
func fill(item:String,count:int) -> void:_arr.resize(count)_arr.fill(item)
# -------------------- 删
# 清除列表项
func remove(idx:int) -> void:_arr.remove_at(idx)
# 清空列表项
func clear() -> void:_arr.clear()
# -------------------- 改
# 修改列表项的值
func set_item(idx:int,new_val:String) -> void:_arr[idx] = new_val# 修改列表项的位置
func move_to(idx:int,new_pos:int) -> void:var item = _arr[idx]_arr.remove_at(idx)_arr.insert(new_pos if new_pos !=0 else 0,item)
# -------------------- 查
# 获取列表项的值
func get_item(idx:int) ->String:return _arr[idx]# 返回列表项的总数
func get_count() ->int:return _arr.size()
# -------------------- 遍历
# 遍历函数
func for_item(callback:Callable) ->void:for i in range(_arr.size()):callback.callv([_arr[i],i,_arr.size()])
# ============================ 获取列表 ============================
# 返回数组的副本
func get_data() -> PackedStringArray:return _arr.duplicate()# 返回有序列表字符串
# 如果show_zero=true,则以最大项序号的位数,在序号之前填充0
func get_OL_string(show_zero:=false) -> String:var s = ""var fm = "%" + "0%dd" % str(_arr.size()).length() if show_zero else "%d" # 以最大项数的位数补全0for i in range(_arr.size()):s+= fm % [i+1] + ".%s" % [_arr[i]]if i != _arr.size()-1:s+= "\n"return s
# 返回有序列表字符串(可直接用于MArkDown)
func get_OL_markdown() -> String:var s = ""for i in range(_arr.size()):s+= "%d. %s" % [i+1,_arr[i]]if i != _arr.size()-1:s+= "\n"return s# 返回html有序列表字符串
func get_OL_html() -> String:var s = "</li>\n\t<li>".join(_arr)return "%s%s%s" % ["<ol>\n\t<li>",s,"</li>\n</ol>"]# 返回html无序列表字符串
func get_UL_html() -> String:var s = "</li>\n\t<li>".join(_arr)return "%s%s%s" % ["<ul>\n\t<li>",s,"</li>\n</ul>"]# 返回无序列表字符串
func get_UL_string(symbol:String = "-") -> String:var s = ""for i in range(_arr.size()):s+= ("%s %s" % [symbol,_arr[i]])if i != _arr.size()-1:s+= "\n"return s
创建实例
我们可以用new()
来创建myList
实例:
var list = myList.new() # 创建实例
或者在new()
中传入一个PackedStringArray
作为初始值:
var list = myList.new(["条目1","条目2","条目3","条目4"]) # 创建实例
添加列表项
除了实例化时直接传入一个字符串数组之外,还可以使用:
append()
:在列表末尾添加一个列表项append_array()
:以字符串数组形式,在列表末尾批量添加列表项fill()
:用指定个数的相同列表项填充列表insert()
:在指定位置插入新的列表项
末尾追加
var list = myList.new(["条目1","条目2","条目3","条目4",]) # 创建实例
list.append("条目5") # 末尾追加
list.append_array(["条目6","条目7","条目8",]) # 末尾追加多项
整体填充
var list = myList.new() # 创建实例
list.fill("这是一个无序列表项",8) # 填充
在指定位置插入
var list = myList.new() # 创建实例
list.fill("这是一个无序列表项",8) # 填充
ist.insert(3,"inset插入的列表项") # 在指定位置插入
对应的有序列表:
1.这是一个无序列表项
2.这是一个无序列表项
3.这是一个无序列表项
4.inset插入的列表项
5.这是一个无序列表项
6.这是一个无序列表项
7.这是一个无序列表项
8.这是一个无序列表项
9.这是一个无序列表项
修改列表项
set_item()
:修改指定项的值move_to()
:修改指定项的位置
修改指定项的值
var list = myList.new() # 创建实例
list.fill("这是一个无序列表项",8) # 填充
list.set_item(3,"修改后的值") # 修改指定位置列表项的值
对应的有序列表:
1.这是一个无序列表项
2.这是一个无序列表项
3.这是一个无序列表项
4.修改后的值
5.这是一个无序列表项
6.这是一个无序列表项
7.这是一个无序列表项
8.这是一个无序列表项
移动列表项
var list = myList.new() # 创建实例
list.fill("这是一个无序列表项",8) # 填充
list.set_item(3,"修改后的值") # 修改指定位置列表项的值
list.move_to(3,6) # 修改列表项位置
对应的有序列表:
1.这是一个无序列表项
2.这是一个无序列表项
3.这是一个无序列表项
4.这是一个无序列表项
5.这是一个无序列表项
6.这是一个无序列表项
7.修改后的值
8.这是一个无序列表项
获取列表项的值
get_item()
:获取指定位置列表项的值
var list = myList.new() # 创建实例
list.fill("这是一个无序列表项",8) # 填充
print(list.get_item(0)) # 获取指定位置列表项的值
输出:
这是一个无序列表项
获取总的列表项数目
get_count()
:获取总的列表项数目
var list = myList.new() # 创建实例
list.fill("这是一个无序列表项",8) # 填充
print(list.get_count()) # 获取总的列表项数目
输出:
8
遍历函数
for_item()
:遍历函数,可以传入一个匿名函数作为回调,包含item
,index
,count
三个参数。- 可以用于快速遍历列表项,执行某些操作
var list = myList.new() # 创建实例
list.fill("这是一个无序列表项",8) # 填充
# 使用遍历函数
list.for_item(func(item,index,count):printt(item,index,count)
)
输出:
这是一个无序列表项 0 8
这是一个无序列表项 1 8
这是一个无序列表项 2 8
这是一个无序列表项 3 8
这是一个无序列表项 4 8
这是一个无序列表项 5 8
这是一个无序列表项 6 8
这是一个无序列表项 7 8
获取列表数据
get_data()
:返回内部数组的副本。
var list = myList.new() # 创建实例
list.fill("这是一个无序列表项",8) # 填充
print(list.get_data()) # 获取列表数据
输出:
["这是一个无序列表项", "这是一个无序列表项", "这是一个无序列表项", "这是一个无序列表项", "这是一个无序列表项", "这是一个无序列表项", "这是一个无序列表项", "这是一个无序列表项"]
有序列表
get_OL_string()
:返回纯字符串形式的有序列表,无法被MarkDown编辑器识别get_OL_markdown()
:返回可以被MarkDown编辑器识别的纯字符串形式有序列表get_OL_html()
:返回HTML形式的有序列表
创建myList
实例:
var list = myList.new(["条目1","条目2","条目3","条目4",]) # 创建实例
list.append("条目5") # 末尾追加
list.append_array(["条目6","条目7","条目8",]) # 末尾追加多项
普通有序列表字符串
print(list.get_OL_string()) # 打印普通有序列表
输出:
1.条目1
2.条目2
3.条目3
4.条目4
5.条目5
6.条目6
7.条目7
8.条目8
get_OL_string()
有一个参数show_zero
,默认为false
,如果设为true
,则会自动在序号前补上0
,序号的总位数取决于最大项序号的位数。
var list = myList.new() # 创建实例
list.fill("这是一个有序列表项",100) # 填充
print(list.get_OL_string(true)) # 获取并打印有序列表
输出:
001.这是一个有序列表项
002.这是一个有序列表项
003.这是一个有序列表项
004.这是一个有序列表项
005.这是一个有序列表项
006.这是一个有序列表项
007.这是一个有序列表项
008.这是一个有序列表项
009.这是一个有序列表项
010.这是一个有序列表项
011.这是一个有序列表项
...
098.这是一个有序列表项
099.这是一个有序列表项
100.这是一个有序列表项
可以被MarkDown编辑器识别的有序列表字符串
print(list.get_OL_markdown()) # 打印可以被MarkDown编辑器识别的有序列表
输出:
1. 条目1
2. 条目2
3. 条目3
4. 条目4
5. 条目5
6. 条目6
7. 条目7
8. 条目8
粘贴到Typora中会被自动识别和转化为有序列表:
HTML形式有序列表
print(list.get_OL_html())
输出:
<ol><li>条目1</li><li>条目2</li><li>条目3</li><li>条目4</li><li>条目5</li><li>条目6</li><li>条目7</li><li>条目8</li>
</ol>
网页浏览器中效果:
无序列表
get_UL_string()
:返回纯字符串形式的有序列表,可以被MarkDown编辑器识别get_UL_html()
:返回HTML形式的有序列表
创建并填充一个无序列表:
var list = myList.new() # 创建实例
list.fill("这是一个无序列表项",8) # 填充
普通无序列表字符串
print(list.get_UL_string()) # 获取并打印无序列表
输出:
- 这是一个无序列表项
- 这是一个无序列表项
- 这是一个无序列表项
- 这是一个无序列表项
- 这是一个无序列表项
- 这是一个无序列表项
- 这是一个无序列表项
- 这是一个无序列表项
起始,这种形式也可以直接被MarkDown编辑器识别为无序列表:
显示自定义符号
get_UL_string()
有一个参数,可以传入自定义的列表符号:
print(list.get_UL_string("*")) # 自定义无序列表符号
* 这是一个无序列表项
* 这是一个无序列表项
* 这是一个无序列表项
* 这是一个无序列表项
* 这是一个无序列表项
* 这是一个无序列表项
* 这是一个无序列表项
* 这是一个无序列表项
print(list.get_UL_string("□")) # 自定义无序列表符号
□ 这是一个无序列表项
□ 这是一个无序列表项
□ 这是一个无序列表项
□ 这是一个无序列表项
□ 这是一个无序列表项
□ 这是一个无序列表项
□ 这是一个无序列表项
□ 这是一个无序列表项
HTML形式无序列表
print(list.get_UL_html())
输出:
<ul><li>这是一个无序列表项</li><li>这是一个无序列表项</li><li>这是一个无序列表项</li><li>这是一个无序列表项</li><li>这是一个无序列表项</li><li>这是一个无序列表项</li><li>这是一个无序列表项</li><li>这是一个无序列表项</li>
</ul>
代码技巧总结
获取数字的位数
对于整数,通过将其转化为字符串,获取长度来获取位数:
print(str(32).length()) # 2
对于浮点数,可以采取类似的方法:
print(str(10.25).length()) # 5
如果需要不包含小数点的位数,早上面的值之上减1就可以了:
print(str(10.25).length()-1) # 4
判断数字是浮点数还是整数
通过判断是否有.
,可以判断数字是不是小数:
print(true if str(10.25).find(".") != -1 else false) # true
print(true if str(100).find(".") != -1 else false) # false
或者更简单的用is
:
print(num is float) # 判断数字是不是浮点数
print(num is int) # 判断数字是不是整数
单独获取浮点数的整数和小数部分,及其位数
我们可以用字符串分割来获取整数部分和小数部分的数字:
print(str(10.25).split(".")[0]) # "10" 浮点数的整数部分
print(str(10.25).split(".")[0].length()) # 2 浮点数的整数部分的位数
print(str(10.25).split(".")[1]) # "25" 浮点数的小数部分位数
print(str(10.25).split(".")[1].length()) # 2 浮点数的小数部分位数
print("0.%s" % str(10.25).split(".")[1]) # "0.25" 浮点数的完整小数部分
构造复杂的多重格式化字符串
var fm = "%" + "0%dd" % str(32).length()
print(fm % 1) # 01
str(32).length()
获取整数32
的位数"%" + "0%dd" % str(32).length()
,首先将替换"0%dd"
中的%d
,变为"02d"
,然后加上之前的%
,构成格式化字符串"%02d"
在整数末尾补0
"%04d" % 123
,返回0123
"%0-4d" % 123
,返回1230
,-实现了在右侧,也就是末尾补0
的效果
print("%0-4d" % 123) # 1230