プレーヤーの持ち物からアイテムを削除するなど、配列の内容を変更したいことが良くあります。Lua 言語には、これを簡単にするために、配列を操作する関数があらかじめ組み込まれています。
ここでは、配列の中から値を検索したり、新たな値を追加したり削除する方法を学びます。
ここで紹介する配列を操作する関数はごく一部です。よく多くの関数を調べたい場合は、テーブル APIのページをご覧ください。
配列への値の追加
配列に新しい値を追加するには、table.insert(array, value) を使用します。2つ目のパラメーターは、文字列、数値、または Player や IntValue などの様々なオブジェクトを指定することができます。
プレーヤーのアイテムを配列に格納していくプログラムを作成してみます。
- layerItemsという名前の空の配列を作成します。「local playerItems = {}」としても構いません。
playerItems = {}
- table.insert() と入力して、要素を配列に追加します。括弧内に、対象となる配列である playerItems を、その後に追加する要素を指定します。今回はテストとして文字列を追加したいと思います。
playerItems = {}
table.insert(playerItems, "Potion")
table.insert(playerItems, "Bread")
table.insert(playerItems, "Sleeping Bag")
print(playerItems )
- プロジェクトを実行します。出力ウィンドで 3 つの点 … を展開すると、playerItems の内容が表示されます。
配列からの値の削除
使用したらなくなるようなアイテムは、配列から要素を削除しなくてはなりません。値を削除するには、table.remove() を使用します。指定したパラメータに応じて、配列の最後の要素を削除するか、特定のインデックスのものを削除するのかを決定できます。
最後の値を削除する
配列の要素を削除する場合は table.remove() を使用します。また、最後の要素を削除するのであれば、パラメータに対象となる配列を渡すだけで完了です。
- 配列の最後の要素は「Sleeping Bag」です。これを削除するには table.remove(playerItems) とします。
playerItems = {}
table.insert(playerItems, "Potion")
table.insert(playerItems, "Bread")
table.insert(playerItems, "Sleeping bag")
table.remove(playerItems)
print(playerItems )
- プロジェクトを実行します。出力ウィンドウで確認してみると、最後の値「Sleeping Bag」は表示されないのが分かると思います。
インデックスを指定しての削除
配列内の特定の位置にある要素を削除するには、2つ目のパラメータに、削除するインデックス番号を指定します。
- 配列1番目の「Potion」を削除してみましょう。table.remove(playerItems, 1) と入力します。
playerItems = {}
table.insert(playerItems, "Potion")
table.insert(playerItems, "Bread")
table.insert(playerItems, "Sleeping bag")
table.remove(playerItems, 1)
print(playerItems )
table.remove()の 2番目のパラメーターは、インデックス値を指定します。「Potion」などと要素を指定するとエラーになります。
- プロジェクトを実行します。最初の値「Potion」が削除されていることを確認します。
配列から値を削除すると、配列のサイズが変更され、削除された後にインデックス値がシフトダウンされます。「Bread」はインデックス1 になり、「Sleeping bag」はインデックス2になります。
配列内の値の検索
配列内の要素を検索する関数もあります。table.find(playerItems, “Bread”) とすると、見つかった場合はそのインデックス番号が返り、見つからなかった場合は nil が返ります。
値を見つける
- table.insert() で要素を追加していっても構いませんが、今回は下記のように事前に値を設定しておきます。
local playerItems = {
"Potion",
"Bread",
"Sleeping Bag"
}
- table.find() 関数を使用して検索してみます。1つ目のパラメータは配列を、2 つ目のパラメータは検索したい値を指定します。返ってきた値を表示してみます。
local playerItems = {
"Potion",
"Bread",
"Sleeping Bag"
}
local index = table.find(playerItems, "Bread")
print(index)
仮に、table.find() 関数を自作した場合は、下記のようなプログラムになるでしょう。
local function find(whichArray, itemName)
for currentIndex = 1, #whichArray do
if whichArray[currentIndex] == itemName then
return currentIndex
end
end
return nil
end
local index = find(playerItems, "Bread")
print(index)
値の削除
table.remove() 関数は、指定したインデックスの削除はできましたが、値を見つけてそれを削除することはできません。下記のようなプログラムを作成することで簡単に実現できます。
- table.find() で値を検索し、見つかったら、 table.remove() を使って削除すれば完成です。
local index = table.find(playerItems, "Bread")
if index then
table.remove(playerItems, index)
end
- 以下のコードを使用して、Breadが削除されたかどうかを確認してみましょう。
for index = 1, #playerItems do
local itemString = playerItems[index]
print("Index " .. index .. ": " .. itemString)
end
特定の値をすべて見つけて削除する
もし「Bread」というアイテムが複数あって、それをすべて削除したい場合はどうでしょうか。table.find() と table.remove()、while ループ、if 文を使えば簡単に実現できると思いますが、ここでは for ループを使った方法でやってみましょう。
- 前準備として、重複するアイテムを持つ配列を用意します。
local playerItems = {
"Potion",
"Bread",
"Bread",
"Sleeping Bag"
}
- 「for index = 1, #playerItems」としたい所なのですが、ちょっと待ってください。アイテムを削除すると、配列がシフトされます。それを考えた場合、インデックス1からではなく、最後のインデックスから始めた方がベストでしょう。
#playerItemsで始まり、1 で終わるという for を作成します。もちろん、インデックス値は減らしていきます。つまり、逆方向に進む for ループを作成するのです。
for index = #playerItems, 1, -1 do
end
仮に"Bread"の削除をインデックス1から始めるとこうなります。まず、index=1で"Postion"は"Bread"でないのでスキップ。index=2は"Bread"なので削除。削除すると2番目の"Bread"("Sleeping Bag"の前のもの)がインデックス2に変わります。しかし自動的に、index=3になりますので、現在の"Sleeping Bag"が参照され、"Bread"が残ってしまうことになります。
- ループ内で if ステートメントを使用して、playerItems[index]内の値が”Bread”と等しいかどうかを確認し、等しい場合はアイテムを削除します。
for index = #playerItems, 1, -1 do
if playerItems[index] == "Bread" then
table.remove(playerItems, index)
end
end
- 以下のコードを使用して、2つのBreadが削除されたかどうかを確認してみましょう。
for index = 1, #playerItems do
local itemString = playerItems[index]
print("Index " .. index .. ": " .. itemString)
end
- スクリプトを実行し、「Bread」という名前の値がすべて削除されていることを確認します。
まとめ
値を配列に削除したり、配列に追加したりすることはできますが、その際にインデックスがシフトすることに注意してください。ループを使用してテーブルを反復処理し、値のすべてのインスタンスを削除するか、最初に見つかったインスタンスのみを削除します。
キーワードreturn を使用すると、ループを停止し、必要に応じて情報を送り返すことができます。
[ 5-2 ループと配列 ]
[ 5-4 辞書の概要 ]