【Godot4.x】Arrayのよく使う関数まとめ

この記事では 配列を扱う Array のよく使う関数についてまとめてみました。

Arrayのよく使う関数まとめ

生成、初期化

生成は基本的に [] を使って行います。

Packed〜Array (例えばPackedInt32Arrayなど)というクラスも存在しているのですが、Godot4.xからArrayで扱う型を指定できるようになったので、生成は [] で書いて変数側に型を指定するという書き方が良さそうです。

# 数値配列の作成
var arr:Array[int] = [1, 2, 3, 4]

要素をすべて初期化するには clear() を使います。

# 数値配列の作成
var arr:Array[int] = [1, 2, 3, 4]
# 要素をすべて消す.
arr.clear()

複製

Arrayを複製するには duplicate() を追加います。

	# 数値配列の作成
	var arr1:Array[int] = [1, 2, 3, 4]
	# 複製.
	var arr2 = arr1.duplicate()
	arr2[0] = 0 # 先頭の要素を書き換えてみる.
	print("arr1: ", arr1)
	print("arr2: ", arr2)
結果
arr1: [1, 2, 3, 4]
arr2: [0, 2, 3, 4]

プログラムに慣れていないとやりがちなミスとして「アドレスコピー」と「実体の複製」を混同することです。

GDScriptのオブジェクトの代入は基本的にアドレスコピーなので、以下の記述だとそれぞれの変数の中身が書き換わってしまいます。(先頭の要素の値がそれぞれ “0” となります)

	# 数値配列の作成
	var arr1:Array[int] = [1, 2, 3, 4]
	# 複製.
	var arr2 = arr1
	arr2[0] = 0 # 先頭の要素を書き換えてみる.
	print("arr1: ", arr1)
	print("arr2: ", arr2)
結果
arr1: [0, 2, 3, 4]
arr2: [0, 2, 3, 4]

要素の追加

要素の追加は append() で行います。(末尾への追加)

	# 数値配列の作成
	var arr1:Array[int] = [1, 2, 3, 4]
	arr1.append(10)
	arr1.append(20)
	print("arr1: ", arr1)
結果
arr1: [1, 2, 3, 4, 10, 20]

先頭・末尾への追加

先頭への追加は push_front() 、末尾への追加は push_back() を使用します。

	# 数値配列の作成
	var arr1:Array[int] = [1, 2, 3, 4]
	arr1.push_front(10) # 先頭へ追加.
	arr1.push_back(20) # 末尾へ追加.
	print("arr1: ", arr1)
結果
arr1: [10, 1, 2, 3, 4, 20]
append()とpush_back() の同じ機能の関数がなぜ存在するのか?

append() と push_back() はどちらも要素を末尾へ追加する関数です。

関数が重複している原因はおそらく GDScript が参考にしているスクリプト言語 Python でのリストへの要素追加が append() となっているためだと思われます。

Arrayを結合する

別のArrayを結合する場合は append_array() を使用します。

	# 数値配列の作成
	var arr1:Array[int] = [10, 25, 40, 99]
	var arr2 = [1, 2, 4]
	arr1.append_array(arr2)
	print(arr1)
結果
[10, 25, 40, 99, 1, 2, 4]

要素の削除

要素の削除は remove_at() / erase() で行うことができます。

	# 数値配列の作成
	var arr1:Array[int] = [10, 25, 40, 99]
	arr1.remove_at(2) # 要素[2] (=40) を削除
	print("arr1: ", arr1)
	arr1.erase(99) # 値 99 を削除
	print("arr1: ", arr1)
結果
arr1: [10, 25, 99]
arr1: [10, 25]

remove_at() は要素番号を指定して削除し、erase() は直接値を指定して値が一致する要素を削除します。

要素を取り出して削除

pop_front() で先頭の要素を取り出して削除、pop_back() で末尾の要素を取り出して削除できます。

	# 数値配列の作成
	var arr1:Array[int] = [10, 25, 40, 99]
	var front = arr1.pop_front() # 先頭を取り出す.
	print("front: ", front)
	print("arr1: ", arr1)
	var back = arr1.pop_back() # 末尾を取り出す.
	print("back: ", back)
	print("arr1: ", arr1)
結果
front: 10
arr1: [25, 40, 99]
back: 99
arr1: [25, 40]

なお要素の位置を指定して取り出し+削除する場合には pop_at() を使います。

要素数の取得

Arrayの要素数は size() で取得できます。

	# 数値配列の作成
	var arr1:Array[int] = [10, 25, 40, 99]
	print(arr1.size())
結果
4

なお要素数が0かどうかを判定する場合には is_empty() という関数で行うこともできます。

指定の値が存在するかどうか

Arrayの中に指定の値があるかどうかを調べるには has() という関数がありますが、個人的には in 演算子を使うとコードを短くかけておすすめです。

	# 数値配列の作成
	var arr1:Array[int] = [10, 25, 40, 99]
	if 10 in arr1:
		print("arr1の中に 10 がある")
		
	if not 100 in arr1: # 否定は "not" を使う.
		print("arr1の中に 100 はない")
結果
arr1の中に 10 がある
arr1の中に 100 はない

要素の取り出し

要素の取り出しは通常 [] 演算子でアクセスします。

	# 数値配列の作成
	var arr1:Array[int] = [10, 25, 40, 99]
	var a = arr1[2]
	print("[2]の要素は ", a)
結果
[2]の要素は 40

ランダムな位置の値を取り出す

Arrayの中からランダムな位置にある値を取り出すには pick_random() を使用します。

	randomize() # 乱数を初期化
	
	var arr = [1, 5, 10, 99]
	var a = arr.pick_random()
	print("a: ", a)

randomize() はゲーム開始時にだけ呼び出せば問題ありません。

順序

ソートする

ソートとは、Arrayの値を特定の順番で並び替えることです。例えばArrayの中身が数値の場合、 sort() を使うと昇順(小さい値から大きい値)に並び替えます。

	# 数値配列の作成
	var arr:Array[int] = [9, 2, 7, 3, 5]
	arr.sort()
	print(arr)
結果
[2, 3, 5, 7, 9]

カスタムソート

数値以外の値をソートする場合、ソートルールが特殊な場合は sort_custom() を使います。

## キャラクター定義.
class Chara:
	var lv:int
	var str:String
	var hp:int
	func _init(_lv:int, _name:String, _hp:int) -> void:
		lv = _lv
		str = _name
		hp = _hp
	func _to_string() -> String:
		return "[%s] Lv:%s HP:%d"%[str, lv, hp]

func _ready() -> void:
	var arr:Array[Chara] = []
	arr.append(Chara.new(5, "勇者", 120))
	arr.append(Chara.new(1, "魔法使い", 30))
	arr.append(Chara.new(4, "戦士", 150))
	
	# カスタムソート (レベルで降順ソートする).
	arr.sort_custom(func(a:Chara, b:Chara): return a.lv > b.lv)
	
	print(arr)
結果
[[勇者] Lv:5 HP:120, [戦士] Lv:4 HP:150, [魔法使い] Lv:1 HP:30]

逆順にする

値の並びを逆にするには reverse() を使用します。

	var arr = [1, 5, 10, 99]
	arr.reverse()
	print(arr)
結果
[99, 10, 5, 1]

シャッフルする

Arrayが持っている値を不規則に入れ替える場合には shuffle() を使用します。

	randomize() # 乱数を初期化
	
	var arr = [1, 5, 10, 99]
	arr.shuffle()
	print(arr)
結果
[99, 10, 1, 5]

高階関数

高階関数とは関数を引数に受け取って、Array内の値に対して処理を行う関数です。

map(): すべての値に対して加工する

map() は Array内の値をすべて加工します。

	var arr = [1, 5, 10, 99]
	# すべての値を10倍する.
	arr = arr.map(func(a): return a * 10)
	print(arr)
結果
[10, 50, 100, 990]

filter(): 指定の条件に一致した値だけにフィルタリングする

filter() は bool を返すラムダ式を渡して、trueとなるものだけにフィルタリングする関数です。

	var arr = [1, 5, 10, 99, 100]
	# 奇数の値のみ取り出す.
	arr = arr.filter(func(a): return a % 2 == 1)
	print(arr)
結果
[1, 5, 99]