This commit is contained in:
Joe 2026-02-02 12:08:47 -06:00
parent a9b4f8e83b
commit e6efc04756
8494 changed files with 495610 additions and 0 deletions

View file

@ -0,0 +1,271 @@
---
title: Intro to arrays
description: Learn how to use arrays in Luau to store multiple values at a time. This tutorial shows how to create and change arrays while making an interactive NPC in Roblox.
next: /tutorials/fundamentals/coding-5/loops-and-arrays
prev: /tutorials/fundamentals/coding-5/landing
---
**Data structures** are how coders store and organize entire sets of data. In Luau, data structures are created with tables. **Tables** can hold any number of values.
This article covers using **arrays**, a specific table type, to create a talking character.
<img src="../../../assets/education/coding-5/coding4_introToTables.jpg" width="75%" />
## Tables
**Tables** are data types that can hold multiple values. Unlike other data types that store a single value, tables don't have a fixed size and can hold a mix of different value types. With tables, you can store items in a player's inventory or create a list of thousands of player names.
### Arrays
There are different types of tables. One type is an **array**, which stores lists of values in a specific order. To create an array, create a variable and assign it curly brackets `{ }`. Separate values within the brackets with commas like below:
`local myArray = {"item1", "item2", 10, workspace.Part, myVariable}`
### Create a talking character
To explore arrays, you'll work with a non-playable character (NPC) that, when clicked, shows a different line of dialogue.
<video controls src="../../../assets/education/coding-5/introArrays_projectTotal_optimized.mp4" width="80%"></video>
This project will use a pre-made NPC model, which includes a partial script and Prompt Detector but lacks dialogue.
1. Download the template NPC.
<a href="../../../assets/education/coding-5/TemplateNPC.rbxm">
<Button variant="contained">Download</Button>
</a>
2. In Explorer, import the NPC by right-clicking on **Workspace** ⟩ **Insert From File** and select the downloaded file.
## Code a dialogue array
These steps use an array to store different phrases for the NPC to say when players interact with it.
1. In the **Explorer**, go to **NPC** ⟩ **ProximityPrompt** ⟩ **ChatManager**.
2. In ChatManager, where marked in the script, create an **empty array** to store dialogue options.
```lua
-- Cycles through chat dialogue when prompt is used
local Chat = game:GetService("Chat")
local prompt = script.Parent
local npc = prompt.Parent
local characterParts = npc.CharacterParts
local head = characterParts.Head
-- Add array here
local dialogueArray = {}
local function speak()
local dialogue = "I've got one thing to say!"
Chat:Chat(head, dialogue)
end
prompt.Triggered:Connect(speak)
```
<Alert severity="warning">
This lesson uses the legacy chat API and is strictly for demonstrating how to use arrays. In real experiences, use `Class.TextChatService`.
</Alert>
3. Within the brackets `{}` of the array just created, type at least three strings of dialogue, separated by commas.
```lua
local dialogueArray = {"Hi!", "Do I know you?", "Goodbye!"}
```
## Use array indexes
Each value in the array is assigned an `index` number. Indexes are assigned to values in the order in which the values are stored. The first value is at index 1, the second at index 2, and so forth.
Some coding languages, like Java, start indexes at 0.
In the array just created, `"Hi"` is at index 1, and `"Goodbye!"` is at index 3.
<table>
<thead>
<tr>
<th>Index</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Hi</td>
</tr>
<tr>
<td>2</td>
<td>Today's a great day!</td>
</tr>
<tr>
<td>3</td>
<td>Good bye!</td>
</tr>
</tbody>
</table>
## Use specific index values
Use index values to assign specific pieces of dialogue to the NPC. To use a value at a specific index, add the index in brackets directly after the array's name, like `dialogueArray[1]`.
1. Replace the `dialogue` variable's default string value with index 2.
```lua
local dialogueArray = {"Hi!", "Do I know you?", "Goodbye!"}
local function speak()
local dialogue = dialogueArray[2]
Chat:Chat(head, dialogue)
end
```
<Alert severity="warning">
If an index doesn't exist, a `nil` error will display in Output. For example, since this array only has three values, using `dialogueArray[4]` will result in an error.
</Alert>
2. Playtest and click the NPC. The second array value should appear in the chat bubble. Try changing the code to test out each value in the table.
<img src="../../../assets/education/coding-5/introArrays_showSpeech.jpg" width="75%" />
## Change dialogue lines
When the player interacts with the NPC, the NPC will always say the same line. That's boring. Instead, use a variable to update which index value to use.
Whenever a player interacts with the NPC, increment the variable value by 1 to display the following line of dialogue.
1. To keep track of the current index, add a new variable named `dialogueIndex`. Set the variable to 1 to start at the beginning of the array.
```lua
local dialogueArray = {"Hi!", "Do I know you?", "Goodbye!"}
local dialogueIndex = 1
```
2. In `speak()`, **replace** the index number in `dialogueArray[2]` with the variable you just created.
```lua
local function speak()
local dialogue = dialogueArray[dialogueIndex]
Chat:Chat(head, dialogue)
end
```
3. At the bottom of the function, add 1 to `dialogueIndex`. The next time `speak()` is called, the dialogue will display the next string.
```lua
local function speak()
local dialogue = dialogueArray[dialogueIndex]
Chat:Chat(head, dialogue)
dialogueIndex += 1
end
```
4. Playtest and click the NPC to see each dialogue string from the array.
<video controls src="../../../assets/education/coding-5/introArray_showDialogIndexes_optimized.mp4" width="75%"></video>
Notice there's an **error** in the Output window once the script reaches the end of the array.
You'll fix this in the next section so the dialogue restarts from the beginning after it shows the last string.
## Array sizes
You can use the size of the array to know when to reset the desired index to 1. Find the **size** of an array by typing `#`, without spaces, before an array's name.
For example: `#dialogueArray`
Check the array's size against the variable's current value to know when it's time to start back at the beginning.
### Restart the dialogue
Use the array size to check when it's time to cycle back to the first piece of dialogue.
1. Add an if statement and check if `dialogueIndex` equals `#dialogueArray`, the total size of this array. If so, then set `dialogueIndex` to 1.
```lua
local function speak()
local dialogue = dialogueArray[dialogueIndex]
Chat:Chat(head, dialogue)
if dialogueIndex == #dialogueArray then
dialogueIndex = 1
end
dialogueIndex += 1
end
```
2. If `dialogueIndex` isn't at the end, it should still add 1 to `dialogueIndex`. Move `dialogueIndex += 1` under an else statement.
```lua
local function speak()
local dialogue = dialogueArray[dialogueIndex]
Chat:Chat(head, dialogue)
dialogueIndex = if dialogueIndex == #dialogueArray then 1 else dialogueIndex + 1
end
```
3. Play and confirm you can cycle through and restart the dialogue.
<video controls src="../../../assets/education/coding-5/introArrays_showFullLoopIndexes_optimized.mp4" width="75%"></video>
## Summary
Data structures are how sets of data are stored. Luau uses tables to create data structures. Arrays are a type of table that can hold ordered lists of information. Each value within the array is assigned an index number, starting with index 1.
This script used an array to create a list of possible dialogue lines for a Non-Playable Character (NPC).
```lua title="Completed script"
-- Cycles through chat dialogue when prompt is used
local Chat = game:GetService("Chat")
local prompt = script.Parent
local npc = prompt.Parent
local characterParts = npc.CharacterParts
local head = characterParts.Head
-- Add array here
local dialogueArray = {"Hi!", "Do I know you?", "Goodbye!"}
local dialogueIndex = 1
local function speak()
local dialogue = dialogueArray[dialogueIndex]
Chat:Chat(head, dialogue)
dialogueIndex = if dialogueIndex == #dialogueArray then 1 else dialogueIndex + 1
end
prompt.Triggered:Connect(speak)
```
### Troubleshooting tips
If the character doesn't go through the array of dialogue, try the following troubleshooting tips.
- Check the if statement that `dialogueIndex` is set back to 1. In the else statement, check that `dialogueIndex` has 1 added to itself.
- When getting the array's size, ensure there are no spaces after the # in `#dialogueArray`.
## Optional challenges
Try one of the optional challenges below.
- Code the script so the NPC's dialogue goes backward through the array. The dialogue index should start at the array length and subtract each time instead of adding.
- Instead of showing dialogue in order, have the NPC show a random line of dialogue each time using `Datatype.Random.new()`. A sample script is included below to reference
```lua
local randomGenerator = Random.new()
-- Shows a new dialogue whenever the NPC is clicked
local function speak()
local randomIndex = randomGenerator:NextInteger(1, #dialogueArray)
local dialogue = dialogueArray[randomIndex]
Chat:Chat(head, dialogue)
end
```

View file

@ -0,0 +1,267 @@
---
title: Intro to dictionaries
description: Learn how to use a dictionary table to tag values within data sets.
next: /tutorials/fundamentals/coding-5/pairs-and-ipairs
prev: /tutorials/fundamentals/coding-5/make-changes-to-arrays
---
Dictionaries are tables that associate names or **keys** with a value instead of an index.
Example:
```lua title="Luau dictionary syntax"
local pet = {
Name = "Bobbie",
Type = "Dog",
}
```
Use dictionaries when you need to label values, not just list them in order as an array does. Practice using dictionaries in this tutorial by manipulating values associated with a player.
## Dictionary syntax
Like arrays, dictionaries are assigned to a variable with curly brackets `{}`. **Key-value pairs** are stored on separate lines followed by a comma. Keys and values can be any data type, including strings, numbers, and variable names.
```lua
local playerNames = {
player1 = "Zap",
player2 = "Kel",
}
print(playerNames["player1"])
```
To reference parts or other instanced objects as keys, use brackets.
```lua
local greenPart = workspace.GreenPart
local redPart = workspace.RedPart
local partList = {
[greenPart] = true,
[redPart] = false,
}
print(partList[redPart])
```
<Alert severity="warning">
Use consistent data types for dictionary keys. Mixing data types, such as using both strings and variables for keys, can lead to inconsistent results when manipulating the array and confuse other coders.
</Alert>
## Create a dictionary
One everyday use of dictionaries is organizing player or character information. These steps explore how a theoretical enemy character's information can be stored and accessed.
1. In a new script, create a dictionary named `enemy`.
```lua
local enemy = {
}
```
2. The first key in the dictionary will track the enemy's name with a variable called `Name`.
```lua
local enemy = {
Name
}
```
3. Assign an enemy name to the key, followed by a comma.
```lua
local enemy = {
Name = "Spike",
}
```
4. Add a second key-value pair for how much health the enemy should have. Remember, keys should always use the same data type, but values don't have to.
```lua
local enemy = {
Name = "Spike",
Health = 1000,
}
```
### Use dictionary values
There are two ways to access dictionary values:
- `tableName["keyName"]` (importantly, note the quotations)
- `tableName.keyName`
```lua
local enemy = {
Name = "Spike",
Health = 1000,
}
print("The villain " .. enemy["Name"] .. " approaches!")
print("The villain " .. enemy.Name .. " approaches!")
```
Which style to use usually depends on the purpose of the table. For tables holding a collection of values like a list of players in a server, coders will usually use `tableName["keyName"]`. For a dictionary used to describe an object, coders are more likely to use `tableName.keyName`.
## Change a dictionary value
Changing a key's value is the same as any other variable; use the equal `=` operator.
1. Beneath the `enemy` table, set the enemy's name to something else.
```lua
local enemy = {
Name = "Spike",
Health = 1000,
}
enemy.Name = "Rana"
print("The enemy's name is " .. enemy.Name)
```
2. Playtest and check the Output window.
## Pre-existing variables as keys
Dictionaries can interact with pre-existing variables declared in other parts of a script. The following coding example uses a variable to add a player's name as a key when they join the experience and then sets their points value to 0.
1. In **ServerScriptService**, create a new script named PlayerPoints. In the script, get the Players Service and create an empty dictionary named `playerPoints`.
```lua
local Players = game:GetService("Players")
local playerPoints = {
}
```
2. Code a local function for setting player points with a parameter for a new player variable. Connect the function to the `Class.Players.PlayerAdded` event.
```lua
local playerPoints = {
}
local function setPoints(newPlayer)
end
Players.PlayerAdded:Connect(setPoints)
```
3. In the function, add a variable to get the player's `Name`, a property in every **Player** object, and a print statement for testing.
```lua
local function setPoints(newPlayer)
local name = newPlayer.Name
print("hello " .. name)
end
```
4. Insert `name` into the `playerPoints` dictionary as a key, and set the value, the player's points, to 0.
```lua
local function setPoints(newPlayer)
local name = newPlayer.Name
print("hello " .. name)
playerPoints[name] = 0
end
```
<Alert severity="warning">
Since `name` was created as a variable, it can be accessed with the actual variable name. If `name` were a key name, it would need to be accessed the same as other strings: `playerPoints["name"]`.
</Alert>
5. Use `name` to print the name of the player and `playerPoints[name]` to print the value of the key matching the variable.
```lua
local function setPoints(newPlayer)
local name = newPlayer.Name
print("hello " .. name)
playerPoints[name] = 0
print(name .. " has " .. playerPoints[name] .. " points.")
end
```
6. Run the project and observe the output.
```lua title="Finished script"
local Players = game:GetService("Players")
local playerPoints = {
}
local function setPoints(newPlayer)
local name = newPlayer.Name
print("hello " .. name)
playerPoints[name] = 0
print(name .. " has " .. playerPoints[name] .. " points.")
end
Players.PlayerAdded:Connect(setPoints)
```
### Optional challenges
Below are some challenges that apply to using dictionaries in different ways. See if you can build out the code for these.
- Create a trap part that does damage over time to a player. Once a player touches the trap, damage them, wait, then allow them to be damaged again.
- Create a function that checks which of two players has the most points by accessing a dictionary.
- Create a cipher, a system of swapping one string for another to create a "secret" code. For example, the letter "A" can be swapped with "G," or the word "apple" can be swapped with "orange."
## Dictionaries and pairs()
`pairs()` is a function that's often used to iterate through **dictionaries**. An example is seen below.
```lua
local myDictionary = {
["Blue Player"] = "Ana",
["Gold Player"] = "Binh",
["Red Player"] = "Cate",
}
for key, value in pairs(myDictionary) do
print(key .. " is " .. value)
end
```
`pairs()` can be used to work with a dictionary element's key, value, or both. In the for loop below, the first variable is the key. The second variable is the value. The dictionary that you want to work with is passed in to `pairs()`.
```lua
local inventory = {
["Gold Bricks"] = 43,
Carrots = 3,
Torches = 2,
}
print("You have:")
for itemName, itemValue in pairs(inventory) do
print(itemValue, itemName)
end
```
When executed, the code will print the following:
```lua
You have:
43 Gold Bricks
3 Carrots
2 Torches
```
## Summary
Dictionaries are tables that use key-value pairs instead of indexed values. Dictionaries and arrays start similarly by assigning curly brackets to a variable. Keep entries separated with commas.
All keys within a dictionary should use the same data type, but the values can mix data types without issue.
The way in which a dictionary is accessed can convey its purpose. A dictionary of enemy properties will likely be accessed with the dot operator, while a list of names will likely use `tableName[keyName]`.
When using brackets, be careful; key names created within the table must be treated as strings: `tableName["keyName"]`. However, when referencing objects like parts, the quotations are not needed: `tableName[keyName]`.
Many scripts need to go through dictionaries or arrays, but you may not always know the start and end of these data structures. For example, a dictionary of players may be changing, or players may have an array inventory of varying sizes.
In these situations, you can use `pairs()` and `ipairs()` in a `for` loop to go through each element without known start and end points. You can also use general iteration through the `in` keyword to loop through elements without the need for `pairs()` or `ipairs()`.

View file

@ -0,0 +1,65 @@
---
title: Arrays and dictionaries
description: Learn how to store data in tables with arrays and dictionaries in Luau.
next: /tutorials/fundamentals/coding-5/intro-to-arrays
prev: /tutorials/fundamentals/coding-4/nested-loops
---
### Series description
Data structures are how coders store and organize entire sets of data. In Luau, data structures are tables. Unlike variables, tables can hold any number of values. Tables can store a list of high scores, a player's inventory, or all of an object's properties. Two types of tables covered in this series are **dictionaries** and **arrays**.
### Objectives and prerequisites
<table>
<tbody>
<tr>
<td width="20%"><b>Learning Objectives</b></td>
<td>
Learn common structures for storing sets of information, such as arrays and dictionaries, and use cases for each structure.
Be able to manipulate data structures, such as adding, removing, or returning values from a structure like an array.
</td>
</tr>
<tr>
<td><b>Prerequisites</b></td>
<td>
Have a general understanding of variables in Luau.
Feel comfortable using conditional statements (`if` and `else`) and loops (`for` and `while`).
</td>
</tr>
</tbody>
</table>
### Series contents
<table>
<thead>
<tr>
<th>Article</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>[Intro to arrays](../coding-5/intro-to-arrays.md)</td>
<td>Learn how to store like groupings of data together with arrays.</td>
</tr>
<tr>
<td>[Loops and arrays](../coding-5/loops-and-arrays.md)</td>
<td>Combine arrays with loops to repeat code with a disappearing path trap.</td>
</tr>
<tr>
<td>[Make changes to arrays](../coding-5/make-changes-to-arrays.md)</td>
<td>Add and remove values in arrays by coding a script to manage a player's inventory</td>
</tr>
<tr>
<td>[Intro to dictionaries](../coding-5/intro-to-dictionaries.md)</td>
<td>Organize complex sets of data with pairs using dictionaries.</td>
</tr>
</tbody>
</table>

View file

@ -0,0 +1,234 @@
---
title: Loops and arrays
description: Learn how to iterate, or go through, arrays in Luau using loops.
next: /tutorials/fundamentals/coding-5/make-changes-to-arrays
prev: /tutorials/fundamentals/coding-5/intro-to-arrays
---
**Arrays** can be combined with loops, such as **while** and **for**, to repeat the same code for each indexed value. For example, teleporting each player in an array to a new place or making an array of parts catch fire.
To explore looping through arrays, create a disappearing bridge path where parts are placed into an array and then made to vanish one by one.
<video controls src="../../../assets/education/coding-5/disappearingHero_16_9web.mp4" width="75%"></video>
## Loop through an array
For the project, find or create a set of three parts to make disappear. The parts must all be anchored.
1. Create three parts. Name the parts in the order they should disappear, Part1, Part2, Part3.
2. In ServerScriptService, insert a new script and create an array to store the parts.
```lua
local pathArray = {
}
```
3. On a single line each, type the name of the parts in the order they should disappear. Using a new line for each value makes it easier to read.
```lua
local pathArray = {
workspace.Part1,
workspace.Part2,
workspace.Part3,
}
```
### Use a for loop with an array
Use a for loop to go through the array and control how fast the parts should disappear in the order the parts are indexed within the array.
1. To control how often a part disappears in seconds, create a variable named `VANISH_RATE`. For testing, it's best to keep it to a small number.
```lua
local VANISH_RATE = 1.5
local pathArray = {
workspace.Part1,
workspace.Part2,
workspace.Part3
}
```
<Alert severity='info'>
**Constants** are variables that shouldn't be changed by any other code in the script. They're likely to need adjusting and are put at the top of the script in `ALL_CAPS` to make them easy to spot.
</Alert>
2. Create a for loop with the following: **Start:** `partIndex = 1`, the index of the first value in the array. **End:** `#pathArray`, the size of that array.
```lua
for partIndex = 1, #pathArray do
end
```
3. So there's a delay before a part disappears, in the loop, add a `Library.task.wait()` using `VANISH_RATE`.
```lua
for partIndex = 1, #pathArray do
task.wait(VANISH_RATE)
end
```
4. To get a part to disappear, create a new variable named `whichPart` and set it equal to `partsArray[partIndex]`. Then, to disappear that part, set it's `CanCollide` property to false and `Transparency` to 1.
```lua
for partIndex = 1, #pathArray do
task.wait(VANISH_RATE)
local whichPart = pathArray[partIndex]
whichPart.CanCollide = false
whichPart.Transparency = 1
end
```
5. Check that parts of the path disappear over time.
<video controls src="../../../assets/education/coding-5/showPathDisappearFirst_web.mp4" width="100%"></video>
### Troubleshooting tips
If the bridge doesn't disappear, check the possible issues below:
**Issue:** Parts disappear too fast or are all gone at the start.
- Depending on how fast your character loads into the experience, the first parts may already be invisible. To address this, add a small wait, such as `task.wait(2)`, at the start of the script.
### Code the second loop
Right now, the parts disappear forever. To make them reappear, create a second for loop that will go through each part and instantly make each piece walkable.
1. After the first loop, add a `Library.task.wait()` to create a short delay before the path reappears.
```lua
for partIndex = 1, #pathArray do
task.wait(VANISH_RATE)
local whichPart = pathArray[partIndex]
whichPart.CanCollide = false
whichPart.Transparency = 1
end
task.wait(1)
```
2. **On your own**, try coding a second for loop that makes the path usable again by changing each part's CanCollide property to true and Transparency to 0. When finished, check your work against the code below.
```lua
-- Reset the path by making all parts walkable again
for partIndex = 1, #pathArray do
local whichPart = pathArray[partIndex]
whichPart.CanCollide = true
whichPart.Transparency = 0
end
```
<Alert severity='warning'>
Unanchored parts will fall through the baseplate when CanCollide is false. If the parts aren't reappearing, and there are no Output errors, anchor the parts and test again.
</Alert>
3. Test the project to confirm that once all parts disappear, they come back.
<video controls src="../../../assets/education/coding-5/showPathDisappearIndexed_web.mp4" width="100%"></video>
## Repeat with a while loop
The parts disappear and reappear, but only once. To make the code keep repeating, nest all of the code within a while loop.
1. At the bottom of the script, create a new while true do loop. Then, **move both** for loops into the while loop.
```lua
while true do
-- Make a part disappear from the array in order
for partIndex = 1, #pathArray do
task.wait(VANISH_RATE)
local whichPart = pathArray[partIndex]
whichPart.CanCollide = false
whichPart.Transparency = 1
end
-- Wait for a second before making the path reappear
task.wait(1)
-- Reset the path by making all parts walkable again
for partIndex = 1, #pathArray do
local whichPart = pathArray[partIndex]
whichPart.CanCollide = true
whichPart.Transparency = 0
end
end
```
2. Check that once all parts disappear, they reappear.
<video controls src="../../../assets/education/coding-5/showPathDisappearIndexed_web.mp4" width="80%"></video>
A finished version of the project can be downloaded.
```lua title="Completed script"
local VANISH_RATE = 1.0
local pathArray = {
workspace.Part1,
workspace.Part2,
workspace.Part3,
}
while true do
-- Make a part disappear from the array in order
for partIndex = 1, #pathArray do
task.wait(VANISH_RATE)
local whichPart = pathArray[partIndex]
whichPart.CanCollide = false
whichPart.Transparency = 1
end
-- Wait for a second before making the path reappear
task.wait(1.0)
-- Reset the path by making all parts walkable again
for partIndex = 1, #pathArray do
local whichPart = pathArray[partIndex]
whichPart.CanCollide = true
whichPart.Transparency = 0
end
end
```
## Arrays and ipairs()
`ipairs()` is used with **arrays**. The "i" in `ipairs()` stands for "index." ipairs() can be used to quickly repeat an operation on a lot of objects, like, say, a folder full of parts.
This will be demonstrated by quickly adding particles to a whole folder of parts.
1. In Workspace, create a folder named PartsFolder. Add as many parts as you like.
2. In ServerScriptService, Create a new script and reference the folder.
3. Use GetChildren() to automatically get an array listing all the objects in the folder.
```lua
local partsFolder = workspace.PartsFolder
-- Gets an array listing the parts in PartsFolder
local partsArray = partsFolder:GetChildren()
```
4. Use `in ipairs(ArrayToUse)` with the for loop to go through partsArray and add particles.
```lua title="Completed script"
-- Gets an array listing the parts in PartsFolder
local partsArray = partsFolder:GetChildren()
-- Adds particles to every part in the array
for index, part in ipairs(partsArray) do
local particles = Instance.new("ParticleEmitter")
particles.Parent = part
end
```
Playtest and watch the particles float up from every part in the folder.
## Summary
Loops can be combined with arrays to work with any number of values quickly. If you want to have exact control over what happens to a few parts and in what order, an array must be hard-coded with specific values.
To work with many parts where order doesn't matter, GetChildren() can create an array of an object's children. Utilizing `ipairs()`, the list can be quickly iterated over without knowing the array's size.

View file

@ -0,0 +1,240 @@
---
title: Make changes to arrays
description: Learn how to add, remove, and find values in an array in Luau using tables.
next: /tutorials/fundamentals/coding-5/intro-to-dictionaries
prev: /tutorials/fundamentals/coding-5/loops-and-arrays
---
An array's contents will often have to be changed, like when needing to remove an item from a player's inventory. Luau has **built-in functions** for use with tables to make this easier.
This article will outline prebuilt functions for tables like add and remove while describing how to search for a value.
To apply these skills, you'll create a script that helps to manage a player's inventory.
<img src="../../../assets/education/coding-5/coding4_arrayFunctions.jpg" width="80%" />
## Add values to arrays
To add a new value to an array, use `table.insert(array, valueToInsert)`. The second parameter can be any value such as a string, number, or entire object, like `Class.Player` or `Class.IntValue`.
To practice, you'll create a script that stores player items in a table, then add to it. Since this example is just a script, it can be used with any file or project. Testing the code will be done using the Output window.
1. Create an empty array named `playerItems`.
```lua
playerItems = {}
```
2. Add inventory items to the array by typing `Library.table.insert()`. In the parenthesis, type `playerItems`, the table to add to, followed by a string for each item. Insert at least three values.
```lua
playerItems = {}
table.insert(playerItems, "Potion")
table.insert(playerItems, "Bread")
table.insert(playerItems, "Sleeping Bag")
print(playerItems)
```
3. Run the project. In Output, expand the three dots `...` to see the printed table.
## Remove values from arrays
To remove a value, like if a player used an item or someone in a list of active players leaves an experience, use `Library.table.remove()`. Depending on the parameters provided, the function can either remove the last value of a table, or at a specific index.
### Remove the last value
Sometimes a script needs to remove a specific item. For instance, removing the first item in a player's inventory, or picking the first player in a list. To remove the last value in an array, use `Library.table.remove(arrayName)`. In this use case, the only parameter needed is the table itself.
1. Use the array of items from the previous example. Then, to remove the last value from the table, in this case `"Sleeping Bag"`, type `Library.table.remove(playerItems)`
```lua
playerItems = {}
table.insert(playerItems, "Potion")
table.insert(playerItems, "Bread")
table.insert(playerItems, "Sleeping bag")
table.remove(playerItems)
print(playerItems)
```
2. Run the project. In the Output window, the last value, `"Sleeping Bag"`, shouldn't print.
### Remove by index
To remove a value at a specific point in the array, input in the second parameter the index to remove, such as `table.remove(arrayName, 1)`.
1. Using the same table, type `Library.table.remove()`. In the parameters, input the name of the table and `1`, the value to remove.
```lua
playerItems = {}
table.insert(playerItems, "Potion")
table.insert(playerItems, "Bread")
table.insert(playerItems, "Sleeping bag")
table.remove(playerItems, 1)
```
<Alert severity="warning">
The second parameter for `Library.table.remove()` only accepts a numerical index. Typing something like `"Potion"` will create an error.
</Alert>
2. Run the project. Check that the first value, "Potion" was removed.
<Alert severity="info">
Notice also that all the index values changed or have been pushed. Removing a value from an array will change the array size and shift index values **down** after the one removed. `"Bread"` is now index 1, and `"Sleeping Bag"` is now index 2.
</Alert>
## Search for values in an array
To find specific values in arrays, like the name of a winning player, use the `Library.table.find()` function. Alternatively, you can code your own search function using `for` loops and `if` statements.
### Find and return a single value
To find a value in an array, create a function named `findValue()` that goes through an array and stops the first time it finds a matching value.
Once it finds the value, the function will use the `return` keyword to return that value's index. With an index, you can remove it from the array.
1. Copy the array named `playerItems` below.
```lua
local playerItems = {
"Potion",
"Bread",
"Bread",
"Sleeping Bag"
}
```
2. Code a new function named findValue() with two parameters:
- `whichArray` - the array to search through.
- `itemName` - the specific string to check for.
```lua
local function findValue(whichArray, itemName)
end
```
3. In `findValue()`, use a for loop to check if any value in the array matches `itemName`. If the value matches, use the keyword `return` to return the value found in `currentIndex`.
```lua
local function findValue(whichArray, itemName)
for currentIndex = 1, #whichArray do
if whichArray[currentIndex] == itemName then
return currentIndex
end
end
end
```
4. Test the search function by creating a variable named `valueFound` and calling `findValue()`. Pass in the array to search, and what value it should search for. **Run** the code to confirm that the expected output is index 2.
```lua
local function findValue(whichArray, itemName)
for currentIndex = 1, #whichArray do
if whichArray[currentIndex] == itemName then
--Sends the value of currentIndex back
return currentIndex
end
end
end
local valueFound = findValue(playerItems, "Bread")
print("The value is at index " .. valueFound)
```
### Remove a value
If a value was found using the find function, it can be removed. Check if a value was found with an if statement.
1. Check if a value is inside `valueFound`; if so, remove the value using `Library.table.remove()`.
```lua
if valueFound then
table.remove(playerItems, valueFound)
end
```
2. Print out the array using the code below.
```lua
for index = 1, #playerItems do
local itemString = playerItems[index]
print("Index " .. index .. ": " .. itemString)
end
```
3. Playtest and check that the first `"Bread"` value was removed from the array. Try removing other values by changing the second parameter in `findValue()`.
Notice that because this function was called once, only the first instance of `"Bread"` was removed. The following section will cover how to find and remove all instances.
## Find and remove all of a specific value
While the previous code could only remove the first instance of a value found, this code snippet will find and remove all occurrences from an array. For example, if, say, a player wanted to sell all their bread at an in-game store.
1. Use an array named `playerItems` with at least four values and a set of **duplicates**.
```lua
local playerItems = {
"Potion",
"Bread",
"Bread",
"Sleeping Bag"
}
```
2. To go through the array, create a for loop that goes **backward** through `playerItems`, starting at `#playerItems`, ending at 1, and incrementing by -1.
```lua
for index = #playerItems, 1, -1 do
end
```
<Alert severity="warning">
Remember, removing items causes later indexes to shift. By starting at the end, you avoid skipping a value that may have shifted if you started at the beginning.
</Alert>
3. In the loop, use an if statement to check if the value inside `playerItems[index]` is equal to `"Bread"`, and if so, remove the item.
```lua
for index = #playerItems, 1, -1 do
if playerItems[index] == "Bread" then
table.remove(playerItems, index)
end
end
```
4. Use the code below to add a second for loop that prints the array.
```lua
for index = 1, #playerItems do
local itemString = playerItems[index]
print("Index " .. index .. ": " .. itemString)
end
```
5. Run the script and check that all values named "Bread" are removed.
## Summary
Values can be removed or added to an array, but be careful of indexes shifting doing so. Use loops to iterate through a table to remove all instances of a value, or just the first instance found.
The keyword `return` can be used to stop a loop, and send information back where needed.
A finished version of the script can be referenced below.
The following project includes all scripts in this tutorial. Download [here](../../../assets/education/coding-5/Making_Changes_to_Arrays_-_Final_Project.rbxl).
Note all scripts are in **ServerScriptService** and **disabled**. To use a script, in its properties, uncheck the Disabled field and run Studio.
<Alert severity="info">
For complete list of all table functions, go to `Library.table|Table API`
</Alert>

View file

@ -0,0 +1,165 @@
---
title: pairs and ipairs
description: pairs() and ipairs() are used to go through Luau tables. This lesson covers how to code them for a script and when to use them.
next: /tutorials/fundamentals/coding-5/return-values-from-tables
prev: /tutorials/fundamentals/coding-5/intro-to-dictionaries
---
Many scripts will often need to go through dictionaries or arrays. But sometimes, you may not know the start and end of these data structures. For example, a dictionary of players may be changing, or players may have an array inventory of varying sizes.
In these situations, you can use `pairs()` and `ipairs()`. These can be used with a for loop to go through each element without known start and end points.
This article will cover using them, and have a practical script example where you track restaurant orders in a cooking game.
## Dictionaries and pairs()
`pairs()` is used with **dictionaries**. An example is seen below.
```lua
local myDictionary = {
["Blue Player"] = "Ana",
["Gold Player"] = "Binh",
["Red Player"] = "Cate",
}
for key, value in pairs(myDictionary) do
print(key .. " is " .. value)
end
```
`pairs()` can be used to work with a dictionary element's key, value, or both. In the for loop below, the first variable is the key. The second variable is the value. The dictionary that you want to work with is passed in to `pairs()`.
```lua
local inventory = {
["Gold Bricks"] = 43,
Carrots = 3,
Torches = 2,
}
print("You have:")
for itemName, itemValue in pairs(inventory) do
print(itemValue, itemName)
end
```
When executed, the code will print the following:
```lua
You have:
43 Gold Bricks
3 Carrots
2 Torches
```
## Arrays and ipairs()
`ipairs()` is used with **arrays**. The "i" in `ipairs()` stands for "index." Use ipairs() and arrays in combination with a for loop to work with ordered values like leaderboards. An example is below.
```lua
local players = {"Ali", "Ben", "Cammy"}
for playerRank, playerName in ipairs(players) do
print("Winner #" .. playerRank .. " is " .. playerName)
end
```
When executed, the code will print the following:
```lua
Winner #1 is Ali
Winner #2 is Ben
Winner #3 is Cammy
```
## Practice - Restaurant Soup Simulator
Let's make some soup for a restaurant simulator where players pick from a list of possible soup ingredients. The ingredients will be stored as keys, and the values will start off as false so the players only get what they select.
Use `pairs()` to see what was picked, and then `ipairs()` to print the list of ingredients.
1. Create a new **dictionary** named `menu`. Add 3 - 5 key-value pairs where the key is the ingredient and the value is false.
```lua
local menu = {
cabbage = false,
beef = false,
tomato = false,
noodles = false,
}
```
2. Beneath the menu dictionary, add an **empty array** which will be filled with the customer's choices later.
```lua
-- Customer's soup
local selectedIngredients = {}
```
3. Use `pairs()` to check if each ingredient in the dictionary is marked true or false. If true, add the ingredient to soup.
```lua
-- Customer's soup
local selectedIngredients = {}
-- Adds customer's choices to their soup
for menuChoice, value in pairs(menu) do
if value then
table.insert(selectedIngredients, menuChoice)
end
end
```
4. Repeat the order back to the customer. In the script, code the following below.
- Check if there is a menu item in `selectedIngredients`. If so, print `"You ordered soup with: "`.
- Use `ipairs()` to go through the `selectedIngredients` array and print each ingredient.
- Test by changing at least one menu item to true.
```lua
-- Prints soup order from "selectedIngredients"
if #selectedIngredients > 0 then
print("You ordered soup with: ")
for index, soupIngredient in ipairs(selectedIngredients) do
print(soupIngredient)
end
end
```
5. In the if statement that checks if there is a menu item, add an else condition which tells customers if no ingredients were selected.
```lua
if #selectedIngredients > 0 then
print("You ordered soup with: ")
for index, soupIngredient in ipairs(selectedIngredients) do
print(soupIngredient)
end
else
print("Nothing was selected. Are you not hungry?")
end
```
<Alert severity="info">
The above step is an example of error checking in computer science. It's always a good practice to code what happens if there's a missing value possible in your code. If not, it's possible there might be an error during run time.
</Alert>
## Optional challenges
Below are some challenges that apply using pairs and ipairs in different ways. Try seeing if you can build out the code for these.
**Challenge**: Create a Waiter NPC
Instead of using the Output window, use the NPC from [Intro To Arrays](../coding-5/intro-to-arrays.md) to create a waiter to take customer orders.
**Challenge**: Allow Players to Place Orders
Allow players to select an ingredient by touching a physical part such as a proximity prompt. For more information, see [Proximity Prompts](../../../ui/proximity-prompts.md).
**Advanced Challenge**: Make Me Some Soup Simulator
Create a restaurant simulator where players are the chefs! Players will have to put together ingredients to match the order given to them by the waiter.
1. Create in-game props for 3 - 5 different ingredients.
2. Create 3 - 5 recipes using dictionaries similar to the one in this lesson.
3. Create an array that holds all of the recipes.
4. Randomly select a recipe and use an NPC to tell players what the ingredients are.
5. Create a new dictionary to make a recipe based off which prop ingredients the player touches.
6. Compare the player's recipe to the recipe chosen by the NPC.
7. Increase the challenge by adding an extra condition, such as a timer.

View file

@ -0,0 +1,68 @@
---
title: Return values from tables
description: Learn how to write a search function using pairs and ipairs to return values from tables in Luau.
next: /tutorials/fundamentals/coding-6/landing
prev: /tutorials/fundamentals/coding-5/pairs-and-ipairs
---
A common need in many data structures is to return values. This article will cover searching a table using `pairs()` or `ipairs()` for half of any table element, such as the key or value, to find and return the other half.
The example uses an array listing ships waiting to be repaired. `ipairs()` is used to return a ship's place in line.
```lua
local shipToFind = "Void Racer"
-- Ships waiting for repair
local waitingShips = {"Battle Sun", "Void Racer", "The Big Slow"}
-- Get place in line
local function getPlaceInLine(shipName)
for placeInLine, ship in ipairs(waitingShips) do
if ship == shipName then
return placeInLine
end
end
end
--Print place in line
local placeInLine = getPlaceInLine(shipToFind)
print("Your place in line is " .. placeInLine)
```
## Dictionary search example
Have you ever searched for a lost pet in house going room by room? On your own code a function to search through a dictionary named house to see which room holds a lost puppy.
1. Copy the dictionary below to act as the house.
```lua
local house = {
kitchen = "pile of Junk",
livingRoom = "kitten",
bedroom1 = "nobody there",
bedroom2 = "puppy",
}
```
2. Create a new function called `findPet()` to search the dictionary. Include parameters for what dictionary to search, and what value to search for.
3. Use `pairs()` to iterate through the dictionary. Try coding your own before checking your work in the solution below.
```lua
local function findPet(whereToSearch, searchFor)
for place, value in pairs(whereToSearch) do
end
end
```
4. As the for loop iterates through the dictionary, use `return` to pass back the room where the pet was found.
```lua
local function findPet(whereToSearch, searchFor)
for place, value in pairs(whereToSearch) do
if value == searchFor then
return place
end
end
end
```