【Godot4.2】普通数组Array使用全解析
本篇总结和介绍一下Godot普通数组Array的一些常见用法,包括增、删、查、改和排序、去重、元素计数以及批量操作等。Godot4.2的数组可以分为普通数组Array)、类型化数组)和紧缩数组【Godot4.2】GDScript数组分类及类型化数组和紧缩数组概述一文。@toolvar arr = ["百度","阿里巴巴","美团","支付宝"];# 原始数组arr.shuffle() # 打乱顺序
概述
本篇总结和介绍一下Godot普通数组Array
的一些常见用法,包括增、删、查、改和排序、去重、元素计数以及批量操作等。
- Godot4.2的数组可以分为普通数组(
Array
)、类型化数组(Array[type]
)和紧缩数组(Packed*Array
),具体内容可见:【Godot4.2】GDScript数组分类及类型化数组和紧缩数组概述 一文。
创建数组
创建普通数组,主要有两种方法,一种是构造函数,一种是方括号指定元素的形式。
var arr = Array(); # 构造函数形式创建空数组
var arr2 = []; # 方括号形式创建空数组
var arr3 = [1,2,"张三"] # 方括号形式创建非空数组
利用全局range()函数创建数组
var arr = range(10); # 创建数组
print(arr) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
获取元素
var arr = range(10); # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 下标形式
print(arr[0]) # 0
print(arr[9]) # 9
print(arr[10]) # 下标超出范围,报错
# 方法形式
print(arr.front()) # 0
print(arr.back()) # 9
@tool
extends EditorScript
func _run():
var arr = [1,2,3];
print(arr.front()); # 1 # 相当于arr[0]
print(arr.back()); # 3 # 相当于arr[arr.size()-1]
arr.front()
相当于arr[0]
,arr.back()
相当于arr[arr.size()-1]
。但两种写法在空数组时都会报错:
@tool
extends EditorScript
func _run():
var arr = [];
print(arr[0]); # 报错
print(arr[arr.size()-1]); # 报错
@tool
extends EditorScript
func _run():
var arr = [];
print(arr.front()); # 报错
print(arr.back()); # 报错
添加元素
@tool
extends EditorScript
func _run():
var arr = [1,2,4]; # 原始数组
arr.push_front(0); # 在数组起始(下标0)位置添加新元素
print(arr); # [0, 1, 2, 4]
arr.push_back(5); # 在数组末尾(下标size()-1)位置添加新元素
print(arr); # [0, 1, 2, 4, 5]
arr.append(6) # 在数组末尾(下标size()-1)位置添加新元素
print(arr); # [0, 1, 2, 4, 5, 6]
arr.append_array([7,8,9]); # 在末尾追加数组
print(arr); # [0, 1, 2, 4, 5, 6, 7, 8, 9]
arr += [10,11,12]; # 在末尾追加数组
print(arr); # [0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12]
arr.insert(3,3); # 在指定下标位置添加新元素
print(arr); # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
删除元素
@tool
extends EditorScript
func _run():
var arr = [1,2,3,4,5,6]; # 原始数组
arr.remove_at(0); # 移除指定下标位置的元素,不返回任何值
print(arr); # [2, 3, 4, 5, 6]
arr.pop_at(0); # 移除指定下标位置的元素,并返回该元素
print(arr); # [3, 4, 5, 6]
arr.pop_front() # 移除并返回数组的第一个元素。等效于pop_at(0)
print(arr); # [4, 5, 6]
arr.pop_back() # 移除并返回数组中的末尾元素。等效于pop_at(size()-1)
print(arr); # [4, 5]
arr.erase(4) # 移除数组中第一个匹配的值
print(arr); # [5]
arr.clear() # 清空数组
print(arr); # [] # 清空数组,等价于arr.resize(0)
print(arr.is_empty()); # true
批量处理
all()判断所有元素是否都符合某一条件
@tool
extends EditorScript
func _run():
var arr = [1,2,3];
# 判断数组中的元素是不是全大于5
var result = arr.all(func(num):
return num > 5;
)
print(result) # false
any()判断所有元素是否至少有一个满足条件
@tool
extends EditorScript
func _run():
var arr = [1,2,3];
# 判断数组中有没有大于5的数
var result = arr.any(func(num):
return num > 5;
)
print(result) # false
@tool
extends EditorScript
func _run():
var arr = [1,2,3,10,34,56];
# 判断数组中有没有大于5的数
var result = arr.any(func(num):
return num > 5;
)
print(result) # true
filter()过滤出满足某一条件的所有元素
@tool
extends EditorScript
func _run():
var arr = [1,2,3,10,34,56];
# 判断数组中的元素是不是全大于5
var result = arr.filter(func(num):
return num > 5;
)
print(result) # [10, 34, 56]
map()对所有元素进行统一的处理
所有元素+5
@tool
extends EditorScript
func _run():
var arr = [1,2,3,10,34,56];
# 对所有元素进行处理,然后返回新数组
var result = arr.map(func(num):
return num + 5;
)
print(result) # [6, 7, 8, 15, 39, 61]
所有元素变为原来的2倍
@tool
extends EditorScript
func _run():
var arr = [1,2,3,10,34,56];
# 对所有元素进行处理,然后返回新数组
var result = arr.map(func(num):
return num * 2;
)
print(result) # [2, 4, 6, 20, 68, 112]
将所有元素变为字符串类型
@tool
extends EditorScript
func _run():
var arr = [1,2,3,10,34,56];
#
var result = arr.map(func(num):
return str(num);
)
print(result) # ["1", "2", "3", "10", "34", "56"]
reduce()累计结果
数组元素求和
@tool
extends EditorScript
func _run():
var arr = [1,2,3,4,5,6];
# 对数组元素累加,其中a可以指定一个基数,结果将累加在这个基数上,不指定则默认为第一个元素的值
var result = arr.reduce(func(a,num):
return a + num;
)
print(result) # 21
func _run():
var arr = [1,2,3,4,5,6];
# 数组元素累加
var result = arr.reduce(func(a,num):
return a + num;
,30) # 指定a为30,则整个结果变为 30 + 1 + 2 + 3 + 4 + 5 + 6
print(result) # 51
数组元素求积
@tool
extends EditorScript
func _run():
var arr = [1,2,3,4,5,6];
# 数组元素累乘
var result = arr.reduce(func(a,num):
return a * num;
)
print(result) # 720
字符串连接的reduce实现形式
@tool
extends EditorScript
func _run():
var arr = ["张三","李四","王五"];
#
var result = arr.reduce(func(a,item):
return "%s,%s" % [a,item];
)
print(result) # 张三,李四,王五
@tool
extends EditorScript
func _run():
var arr = ["张三","李四","王五"];
#
var result = arr.reduce(func(a,item):
return "%s,%s" % [a,item];
,"二麻子")
print(result) # 二麻子,张三,李四,王五
count()获取元素出现的次数
@tool
extends EditorScript
func _run():
var arr = ["张三","李四","王五","二麻子","李四",];
print(arr.count("李四")) # 2
fill()填充或初始化所有数组元素
@tool
extends EditorScript
func _run():
var arr = []; # 创建空数组
arr.resize(10); # 重新设定数组大小
arr.fill(0); # 数组的所有元素填充为0
print(arr) # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
如果是非空数组,被fill()
后原来的元素会被全部修改为填充的元素。
@tool
extends EditorScript
func _run():
var arr = [12,34,56]; # 创建数组
arr.fill(0); # 数组的所有元素修改为0
print(arr) # [0, 0, 0]
默认,如果创建空数组后,只resize()
不填充,则所有元素为null
:
var arr = []; # 创建数组
arr.resize(4); # 重新设定数组大小
print(arr) # [<null>, <null>, <null>, <null>]
不要只拘泥于数字,数组中的元素可以是任意的简单类型、符合类型以及对象。
@tool
extends EditorScript
func _run():
var arr = []; # 创建数组
arr.resize(4); # 重新设定数组大小
arr.fill(Vector2.ZERO); # 初始化为0向量
print(arr) # [(0, 0), (0, 0), (0, 0), (0, 0)]
查找
find() & rfind()
find()返回找到的第一个相同元素的位置,找不到返回-1。
rfind()从末尾开始逆序查找,返回找到的第一个相同元素的位置(索引),找不到返回-1。
@tool
extends EditorScript
func _run():
var arr = [0, 1, 2, 3, 4, 5, 6, 4, 8, 9];
print(arr.find(4)) # 4 -- 从左往右 - 正序查找,返回查找到的[第一个]元素的 - 正序索引
print(arr.rfind(7)) # 7 -- 从右往左 - 逆序查找,返回查找到的[第一个]元素的 - 正序索引
两者都可以定义第二个参数,决定从哪个位置开始。
has()判断数组中是否存在某元素
@tool
extends EditorScript
func _run():
var arr = [0, 1, 2, 3, 4, 5, 6, 4, 8, 9];
print(arr.has(9)); # true
print(arr.has(10)); # false
等效写法为元素 in 数组
:
@tool
extends EditorScript
func _run():
var arr = [0, 1, 2, 3, 4, 5, 6, 4, 8, 9];
print(9 in arr); # true
print(10 in arr); # false
只读
@tool
extends EditorScript
func _run():
var arr = [1,2,3,4,5,6]; # 原始数组
arr.make_read_only()
print(arr.is_read_only()) # true
arr.append(7) # 报错:Array is in read-only state.
求最大、最小
@tool
extends EditorScript
func _run():
var arr = [1,2,3,4,5,6]; # 原始数组
print(arr.min()) # 1
print(arr.max()) # 6
@tool
extends EditorScript
func _run():
var arr = [Vector2(0,0),Vector2(40,10),Vector2(100,100)]; # 原始数组
print(arr.min()) # (0,0)
print(arr.max()) # (100,100)
随机
pick_random()从数组中随机选取一个元素
@tool
extends EditorScript
func _run():
var arr = [2,6,9]; # 原始数组
print(arr.pick_random()) # 从数组的3个元素中随机选取一个返回
shuffle()打乱元素顺序
@tool
extends EditorScript
func _run():
var arr = [2,6,9]; # 原始数组
arr.shuffle() # 打乱原来数组元素的顺序
print(arr) # 每次结果不一样
排序
reverse() 将数组中的元素逆序排列
@tool
extends EditorScript
func _run():
var arr = range(10); # 原始数组
print(arr) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
arr.reverse() # 将数组中的元素逆序排列。
print(arr) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
sort()升序,sort()+reverse()降序
@tool
extends EditorScript
func _run():
var arr = range(10); # 原始数组
arr.shuffle() # 打乱顺序
print(arr) # [9, 7, 3, 1, 4, 2, 8, 6, 0, 5]
arr.sort() # 将数组中的元素升序排列
print(arr) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
arr.reverse() # 升序+逆序=降序
print(arr) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
sort_custom()自定义函数进行排序
@tool
extends EditorScript
func _run():
var arr = ["百度","阿里巴巴","美团","支付宝"]; # 原始数组
arr.shuffle() # 打乱顺序
print(arr) # ["阿里巴巴", "百度", "支付宝", "美团"]
# 将数组中的元素按字符串长度降序排列
arr.sort_custom(func(a:String,b:String):
return true if a.length() > b.length() else false
)
print(arr) # ["阿里巴巴", "支付宝", "百度", "美团"]
@tool
extends EditorScript
func _run():
var arr = ["百度","阿里巴巴","美团","支付宝"]; # 原始数组
arr.shuffle() # 打乱顺序
print(arr) # ["支付宝", "阿里巴巴", "百度", "美团"]
# 将数组中的元素按字符串长度升序排列
arr.sort_custom(func(a:String,b:String):
return true if a.length() < b.length() else false
)
print(arr) # ["百度", "美团", "支付宝", "阿里巴巴"]
assign()覆盖
@tool
extends EditorScript
func _run():
var arr1 = ["百度","阿里巴巴","美团","支付宝"]; # 数组1
var arr2 = [1,2,3,4] # 数组2
arr1.assign(arr2); # 用数组2覆盖数组1
print(arr1) # [1,2,3,4]
print(arr2) # [1,2,3,4]
duplicate()创建副本
@tool
extends EditorScript
func _run():
var arr1 = ["百度","阿里巴巴","美团","支付宝"]; # 数组1
var arr2 = arr1.duplicate() # 创建数组1的副本
print(arr1) # ["百度", "阿里巴巴", "美团", "支付宝"]
print(arr2) # ["百度", "阿里巴巴", "美团", "支付宝"]
hash()求数组哈希值
@tool
extends EditorScript
func _run():
var arr = [0, 1, 2, 3, 4, 5, 6, 4, 8, 9];
print(arr.hash()) # 1797923815
:::success
内容相同的 Array 会得到一致的哈希值。然而,反之不然。返回一致的哈希值并不意味着数组相等,因为不同的数组可能因为哈希碰撞而得到一致的哈希值。
:::
判断两个数组是否完全相等,可以使用==
或!=
运算符。
@tool
extends EditorScript
func _run():
var arr1 = [0, 1, 2, 3, 4, 5, 6, 4, 8, 9];
var arr2 = [0, 1, 2, 3, 4, 5, 6, 4, 8, 9];
print(arr1 == arr2) # true
类型化数组与类型判断以及类型转换
Packed*Array
与普通Array
之间可以通过构造函数转化。
@tool
extends EditorScript
func _run():
var arr = PackedStringArray([1,2,4]); # Array转PackedStringArray
print(arr) # ["1", "2", "4"]
与字符串的转化
@tool
extends EditorScript
func _run():
var arr_str = "张三,李四,王五"; # 原始字符串
var arr = arr_str.split(",")
print(arr) # ["张三", "李四", "王五"]
@tool
extends EditorScript
func _run():
var arr = ["张三", "李四", "王五"]; # 原始数组
var arr_str = ",".join(arr);
print(arr_str) # "张三,李四,王五"
数组切分
var arr = ["张三","李四","王五","二麻子"]
arr.slice(0,2) # 等价于
去重
算法1
- 创建一个空数组arr2,通过不断的遍历需要去重的数组arr,判断每个元素是否已经在arr2中:
- 如果存在,直接从arr中删除该元素
- 如果不存在,则将该元素添加到arr2,并从arr中删除
- 不断循环,直到arr为空
# 数组去重 - 算法1
func norepeat(arr:Array) -> Array:
arr = arr.duplicate(true) # 使用副本而不是对原数组进行操作
var arr2 = []
while !arr.is_empty():
for item in arr:
if item not in arr2:
arr2.append(item)
arr.erase(item)
else:
arr.erase(item)
return arr2
@tool
extends EditorScript
func _run():
var arr = [1,2,3,4,5,4,5,4,5,6,7]; # 原始数组
print(norepeat(arr)) # [1, 3, 5, 7, 2, 4, 6]
算法2
- 构造一个空字典dict
- 遍历需要去重的数组arr中的元素item,以
dict[item] = item
形式添加键值对,添加的过程本身就是在去重 - 通过
dict.keys()
或dict.values()
就可以获得去重的数组
# 数组去重 - 算法2
func norepeat2(arr:Array) -> Array:
arr = arr.duplicate(true) # 使用副本而不是对原数组进行操作
var dict:Dictionary = {}
for item in arr:
dict[item] = item
return dict.keys() # dict.values()也可以
func _run():
var arr = [1,2,3,4,5,4,5,4,5,6,7]; # 原始数组
print(norepeat2(arr)) # [1, 2, 3, 4, 5, 6, 7]
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)