【16】配列に変更を加える

配列を操作する関数(テーブル関数)

プレイヤーのインベントリからアイテムを削除する場合など、配列の内容を変更しなければならないことがよくあります。Luaには、テーブルを使用するための関数があらかじめ用意されており、簡単に利用することができます。

これらの関数を使用するには、table.と入力し、関数名を追加します。
例:table.insert()
下の例では、insert() 関数が myPartArray のテーブルにパーツを追加しています。

table.insert(myPartArray, Workspace.Part)

次のセクションでは、インベントリ内のアイテムを追加、削除、検索するための関数を使用します。ターブルの内容はOutputウィンドウに表示します。テーブルで使用できる関数リストの完全版は、ロブロックスの技術情報サイトtable APIページをご覧ください。

配列への値の追加

ゲームが実行されている最中に配列に値を追加したりします。例えば、プレイヤーがパーツにタッチしたら、インベントリにアイテムを追加する場合などです。
配列に新しい値を追加するには、table.insert(array, valueToInsert) を使用します。2 番目のパラメータには、文字列、数値、あるいは Player オブジェクトなど、任意のタイプの値を指定することができます。

  1. playerItems という名前の空の配列を作成します。
playerItems = {}
  1. table.insert() と入力して、インベントリのアイテムを配列に追加します。括弧内に playerItems と追加して、その後に各アイテムの文字列を入れます。3つ以上の値を追加してください。
playerItems = {}
 
table.insert(playerItems, "Potion")
table.insert(playerItems, "Bread")
table.insert(playerItems, "Sleeping Bag")
  1. Outputウィンドウにすべての配列の値を表示するには、下記のように for ループを使用します。
playerItems = {}
 
table.insert(playerItems, "Potion")
table.insert(playerItems, "Bread")
table.insert(playerItems, "Sleeping bag")
 
for index = 1, #playerItems do
    local itemString = playerItems[index]
    print("Index " .. index .. ": " .. itemString)
end

文字列と変数を組み合わせる
文字列と変数または文字列と他の文字列を結合させるには、文字列と変数名の間に「..」と入力します。

  1. プロジェクトを実行します。Output ウィンドウに各アイテム名が表示されるはずです。

様々な種類の値を挿入する
table.insert() を使用して他の値を挿入することもできます。
例:
・table.insert(numberArray, 10) — 数字を挿入
・table.insert(partArray, Workspace.Part1) — パーツを挿入
・table.insert(playerArray, RobloxPlayer) — プレイヤーオブジェクトを挿入

配列から値を削除する

プレイヤーがアイテムを使用した場合や、アクティブになっているプレイヤーがゲームから離れた時など、値を削除したいことがあります。そのような場合は、table.remove(arrayName, index) を使用します。この関数は、テーブルの最後の値を削除するか、指定したインデックスの値を削除します。

最後の値を削除する

  1. 3つ以上の文字列を含む playerItems という名前の配列を作成します。
playerItems = {
    "Potion",
    "Bread",
    "Sleeping Bag"
}
  1. 最後の値 “Sleeping Bag” を削除するには table.remove(playerItems) と入力します。
playerItems = {
    "Potion",
    "Bread",
    "Sleeping Bag"
}
 
table.remove(playerItems)
  1. 配列の内容を表示するには、下記のように for ループを使用します。
for index = 1, #playerItems do
    local itemString = playerItems[index]
    print("Index " .. index .. ": " .. itemString)
end
  1. プロジェクトを実行します。最後の値を削除したため、Outputウィンドウには “Sleeping Bag” が表示されないはずです。

インデックス指定で値を削除する

配列の特定の値を削除するには、table.remove(arrayName, whichIndex) で第2パラメータにそのインデックスを指定します。

  1. 3つ以上の文字列を含む playerItems という名前の配列を作成します。
  2. table.remove() と入力します。最初の値(Potion)を削除するには、そのインデックスであるを第2パラメーターで指定します。
playerItems = {
    "Potion",
    "Bread",
    "Sleeping Bag"
}
 
table.remove(playerItems, 1)

Table.Remove() ではインデックスのみ許容される
table.remove() の第2パラメーターは数字のインデックスのみが指定できます。table.remove(playerItems, “Bread”) のように文字を指定するとエラーになります。なお、数字が入っている変数ならば問題はありません。

  1. 下記のコードを使用して、配列を表示します。
for index = 1, #playerItems do
    local itemString = playerItems[index]
    print("Index " .. index .. ": " .. itemString)
end
  1. プロジェクトを実行します。最初の値 “Potion” が削除されたことを確認します。

すべてのインデックス値が変更されたことに注意してください。配列から値を1つ削除すると配列のサイズが変更され、インデックス値がにずれます。“Bread”はインデックス1になり、“Sleeping Bag”はインデックス 2 になります。

値を探す

勝利したプレイヤーなど、配列内で特定の値を探すには、forループif文を使用して、自分で検索関数をコーディングする必要があります。既成の関数にはありません。

ひとつの値を探す

配列内の値を探したい場合は findValue() という名前の関数を作成します。配列内のすべての値を調べ、見つかったから return キーワードを使用して、その値のインデックスを返します。これにより、配列から特定の値を削除するなどの処理が可能になります。

  1. 下記の playerItems という名前の配列をコピーします。
local playerItems = {
    "Potion",
    "Bread",
    "Bread",
    "Sleeping Bag"
}
  1. 2つのパラメータを持つ、findValue() という名前の新しい関数を作成します。
  • whichArray : 検索する配列
  • itemName : 確認する特定の文字列
local function findValue(whichArray, itemName)

end
  1. findValue()forループを使用し、配列内の値が itemName と一致するかどうかを確認します。値が一致すれば、return キーワードを使用して、現在のインデックス currentIndex 値を返します。
local function findValue(whichArray, itemName)
    for currentIndex = 1, #whichArray do
        if whichArray[currentindex] == itemName then
            return currentIndex
        end
    end
end
  1. valueFound という名前の変数を作成し、検索関数 findValue() を呼び出すことで見つかったインデックスを格納します。
playerItems = {
    "Potion",
    "Bread",
    "Bread",
    "Sleeping Bag"
}
 
local function findValue(whichArray, itemName)
    for currentIndex = 1, #whichArray do
        if whichArray[currentindex] == itemName then
            --currentIndex の値を返す
            return currentIndex
        end
    end
end
 
local valueFound = findValue(playerItems, "Bread")

関数でreturnを使用する
return は関数を停止させ、その関数を呼び出された行に戻します。return キーワードの後ろに何かがある場合は、その情報を関数を通して送り返します。
上記の例では、returncurrentIndex の値を返し、それを findValue() が呼び出された元の変数に格納します。つまり、currentIndexvalueFound は同一の値になっているということです。

見つかった値を使用する

find 機能を使用して見つけた値は削除することができます。スクリプトが存在しない値を削除しようとしてエラーになるのを防ぐため、if文で値が見つかったかを確認します。

  1. valueFound という名前を indexToRemove に変更します。その変数に値が入っているかどうかを確認するために if文を使用します。if文内で table.remove(playerItems, indexToRemove) と入力することにより、見つかった値を削除することができます。
local indexToRemove = findValue(playerItems, "Bread")

if indexToRemove then
    table.remove(playerItems, indexToRemove)
end
  1. 下記のコードを使用して、配列を表示します。
for index = 1, #playerItems do
    local itemString = playerItems[index]
    print("Index " .. index .. ": " .. itemString)
end
  1. プロジェクトを実行し、最初の“Bread”が配列から削除されたことを確認します。2番目のものはそのままになっているはずです。さらにスクリプトをテストするため、findValue() の2つ目のパラメータを変更し、他の値も削除してみましょう。

この関数は一度だけ呼び出されたるので、最初に発見された“Bread”のみ削除します。次のセクションでは、関数のすべてのインスタンスを削除する方法を学びます。

配列で他のタイプの値を探す
関数 findValue() は文字列と数字の値で機能しますが、具体的な値を比較する際には注意を要します。例えば、プレイヤーの場合、次の比較を利用してName値を確認します。

player.Name == “playerNameToCheck”

すべての値を探し削除する

先ほどのコードでは、最初に見つかったデータだけを削除しましたが、今回は配列内のすべての値を見つけて削除します。
項目を削除すると、後ろのインデックスがずれることを覚えておいてください。配列の先頭から始めるのではなく、最後のインデックスから始めると、誤って値を飛ばしてしまうことを防ぐことができます。最後のインデックスから開始することで、それより前の値のインデックスは変更されることはありません。

  1. 4つ以上の値と重複した文字列を含む playerItems という名前の配列を作成します。
local playerItems = {
    "Potion",
    "Bread",
    "Bread",
    "Sleeping Bag"
}
  1. 配列内をすべて見渡すため、forループを使用します。先ほどと異なり、今回は playerItems を逆の方から調べます。#playerItems から始め、1 で終了します。そのため、増加値は-1になります。
for index = #playerItems, 1, -1 do
 
end
  1. ループ内で、if文を使用し、”Bread” に一致した値を、table.remove を使用して削除します。
for index = #playerItems, 1, -1 do
    if playerItems[index] == "Bread" then
        table.remove(playerItems, index)
    end
end
  1. 下記のコードを使用して、配列を表示する2つ目のforループを追加します。
for index = 1, #playerItems do
    local itemString = playerItems[index]
    print("Index " .. index .. ": " .. itemString)
end
  1. スクリプトを実行し、“Bread”という名前の値がすべて削除されていることを確認します。

コメントを残す