# Changing orders of Tables?

Try reading the dev hub article on tables. https://developer.roblox.com/en-us/articles/Table

1 Like

Thank you - I have read through this before, at length, and again recently - I’m still struggling with the situation. Now I’m not that familiar with tables, but what I would do is to rewrite the entire table. But that’s just me, I’m sure there is an easier way to do it.

1 Like

When adding an item at index n, loop `for i = #table, -1, n do`, and move table[i] to table[i + 1]. Then you can put the item in at index n.

Edit: Sample code for clarification

``````local list = {1, 2, 3, 5, 6}

-- move everything behind index back
for i = #list, -1, index do
list[i + 1] = list[i]
end
-- place item in
list[index] = item
end

for i = 1, #list do
print(list[i])
end
-- Output >> 1 2 3 7 5 6
``````
2 Likes

cc @KossmoZ
Just saying, it would most likely be easier to use `table.insert(table, index, value)`. The above is pretty much what the function does behind the scenes, but it’s easier to use.

``````--Sample code
local list = {1, 2, 3, 5, 6}
table.insert(list, 4, 4)

--Same ouput: 1, 2, 3, 4, 5, 6
``````

And a reference article:
table.insert

3 Likes

Wow I completely forgot about that. I was doing it manually, but this way is definitely much more efficient.

3 Likes

Hi, I’m trying to wrap my head around these tables - As your list only lists 1 - 6 with no 4; table.insert would added a fourth variable but what if one were to already exist and just needs moving forward one space? :L

@MayorGnarwhal

Think of it like this:

``````local tableSample = {index 1, index 2, index 3...}
``````

table.insert shoves everything over, then replaces the specified index with the specified value.

``````local sample = {3, 9, 2}
--`3` is at index 1, `9` is at index 2, `2` is at index 2
table.insert(sample, 2, 10) --Table, index, value
--So, the above turns the table into {3, index 2, 9, 2}
--Then: {3, 10, 9, 2}
``````
1 Like
``````local newtable = {one,two,three}
local tablevar = newtable
table.remove(newtable,1)
table.insert(newtable,2,tablevar)

--expect output: two,one,three
``````

Again I’m no master at tables, but I think this may be a simple way to do that.

1 Like

So - As my tables are preset with suches as:

`{inputKeys["One"]; inputKeys["Two"]; inputKeys["Three"]; inputKeys["Four"]; inputKeys["Five"]}`

if I were to use Table.Insert would there not then be six variables?

Full script for reference:
``````local System = {}

local UserInputService = game:GetService("UserInputService")

local CoreGui = script.Parent
local Gui = CoreGui["ToolBar"]

local Player = game:GetService("Players").LocalPlayer

local StarterGui = game:GetService("StarterGui")
local success, result = pcall(StarterGui.SetCoreGuiEnabled, StarterGui, Enum.CoreGuiType.Backpack, false)

local inputKeys =
{["One"] = {Text = "1"};
["Two"] = {Text = "2"};
["Three"] = {Text = "3"};
["Four"] = {Text = "4"};
["Five"] = {Text = "5"}}

local inputOrder =
{inputKeys["One"]; inputKeys["Two"]; inputKeys["Three"]; inputKeys["Four"]; inputKeys["Five"]}

function System:Enable()
local PlayerTools = Player["Backpack"]:GetChildren()
for i = 1, #PlayerTools do wait()
if PlayerTools[i]:IsA("Tool") then
for i = 1, #inputOrder do wait()
local Value = inputOrder[i]
if not Value["Tool"] then
Value["Tool"] = PlayerTools[i]
break
end
end
end
end
Create()
UserInputService.InputBegan:Connect(onKeyPress)
Player.Character.ChildRemoved:Connect(ChildRemoved)
Player["Backpack"].ChildRemoved:Connect(ChildRemoved)
end

function Create()
for i = 1, #inputOrder do wait()
local Value = inputOrder[i]
local Template = script["Template"]:Clone()
Template.Parent = Gui
Template["TextLabel"].Text = Value["Text"]
Template.Name = Value["Text"]

local Tool = Value["Tool"]
if Tool then
if Tool.TextureId == "" then
Template["ItemName"].Text = Tool.Name
else
Template["Item"].Image = Tool.TextureId
end
Template.Visible = true
end

Template["Item"].MouseButton1Down:Connect(function()
for i, Value in pairs(inputKeys) do
if Value["Text"] == Template.Name then
EquipTool(Value["Tool"])
end
end
end)
end
end

function onKeyPress(inputObject)
local Key = inputObject.KeyCode.Name
local Value = inputKeys[Key]
if Value and UserInputService:GetFocusedTextBox() == nil then
EquipTool(Value["Tool"])
end
end

function EquipTool(Tool)
if Tool then
if Tool.Parent ~= Player.Character then
Player.Character:WaitForChild("Humanoid"):EquipTool(Tool)
else
Player.Character:WaitForChild("Humanoid"):UnequipTools()
end
end
end

if Child:IsA("Tool") then
local isNew = true
for _, Value in pairs(inputKeys) do
local Tool = Value["Tool"]
if Tool then
if Tool == Child then
isNew = false
end
end
end
if isNew == true then
if Child.Name == "Tool" then
table.insert(inputOrder, 1, Child)
else
for i = 1, #inputOrder do wait()
local Tool = inputOrder[i]["Tool"]
if inputOrder[i]["Tool"] == Child then
inputOrder[i]["Tool"] = nil
end
if not Tool then
inputOrder[i]["Tool"] = Child
break
end
end
end
end
Configure()
end
end

function ChildRemoved(Child)
if Child:IsA("Tool") then
if Child.Parent ~= Player.Character and Child.Parent ~= Player["Backpack"] then
for i = 1, #inputOrder do wait()
if inputOrder[i]["Tool"] == Child then
inputOrder[i]["Tool"] = nil
break
end
end
for index=1, #inputOrder - 1 do
wait()
local thisItem = inputOrder[index]
local nextItem = inputOrder[index + 1]
if thisItem["Tool"] == nil and nextItem["Tool"] ~= nil then
thisItem["Tool"] = nextItem["Tool"]
nextItem["Tool"] = nil
end
end
end
Configure()
end
end

function Configure()
for _, Value in pairs (inputKeys) do
local Tool = Value["Tool"]
local Item = Gui:FindFirstChild(Value["Text"])
if Tool then
Item.Visible = true
if Tool.TextureId == "" then
Item["ItemName"].Text = Tool.Name
else
Item["Item"].Image = Tool.TextureId
end
if Tool.Parent == Player.Character then
Item.ImageTransparency = .5
else
Item.ImageTransparency = .75
end
else
Item.Visible = false
Item["Item"].Image = ""
Item["ItemName"].Text = ""
end
end
end

System:Enable()

return System
``````

If you use `table.insert`, the length will always be increased by `1`, as a new element is inserted at the specified index, after pushing the rest down.

What exactly do you want your code to do? What’s the before and after?

1 Like

I want it to work where if a new Child is added into the Backpack i.e. collected; and it’s titled: “Wand” then that’s always placed in Slot1 to be the front of the queue.

If any other item is in Slot1 at the time of collection, i.e. “Potion” then when “Wand” becomes Slot1; Potions becomes Slot2 and carrying on for others if found.

You can achieve this by doing:

``````table.insert(slots, 1, newItem)
``````

This will bring the new item to the front.

Are you using a custom backpack / hotbar?

2 Likes

Is there a cap to how many tools can be in backpack? Your code seems to be structured that way.

If there can only be 5 tools, and the player picks up a 6th then you can do a few things;

• Force drop the incoming tool
• Drop the tool previously in the first slot
• Insert the tool, and then remove the 6th index
1 Like

I am.

ToolBarGui.rbxm (9.8 KB)

@MayorGnarwhal - Oooh I didn’t actually think that far ahead! I’ll look into that.

Using table.insert() I’m met with the error:
[Tool is not a valid member of Tool] in my ChildRemoved function.

Currently this is how I’m working on moving the indexes forward by one however I am currently experiencing some unintended bugs that are causing the other segments of the table to become occupied by multiple of the same tools.

``````    for i = 1, #inputOrder - 1 do wait()
local currentIndex = inputOrder[i]
local nextIndex = inputOrder[i + 1]
if currentIndex["Tool"] ~= nil then
nextIndex["Tool"] = currentIndex["Tool"]
currentIndex["Tool"] = nil
end
end
inputOrder["Tool"] = Child``````

I’m slowly but surely getting there.
As you can see - It successfully takes up Slot1; however, it also occupies and replaces Slot3:

https://gyazo.com/eb01677926967f53665d93a0cda5c0f9

``````			for i = 1, #inputOrder - 1 do wait()
local currentIndex = inputOrder[i]
local nextIndex = inputOrder[i + 1]
if currentIndex["Tool"] ~= nil and currentIndex["Tool"] == not currentIndex["Tool"] then
nextIndex["Tool"] = currentIndex["Tool"]
currentIndex["Tool"] = nil
break
end
inputOrder["Tool"] = Child
end``````

I’ve "DONE" it!
Not in the way I would of liked but it’s a start!

``````		if isNew == true then
if Child.Name == "Tool" then
local Ex1 = inputOrder["Tool"]
local Ex2 = inputOrder["Tool"]
local Ex3 = inputOrder["Tool"]
local Ex4 = inputOrder["Tool"]
local Ex5 = inputOrder["Tool"]

print(inputOrder["Tool"], inputOrder["Tool"], inputOrder["Tool"])

inputOrder["Tool"] = Child
inputOrder["Tool"] = Ex1
inputOrder["Tool"] = Ex2
inputOrder["Tool"] = Ex3
inputOrder["Tool"] = Ex4

print(inputOrder["Tool"], inputOrder["Tool"], inputOrder["Tool"])``````
1 Like

Final result:

``````				local Pre = {}
for i = 1,#inputOrder do wait()
table.insert(Pre, i, inputOrder[i]["Tool"])
end
for i = 1,#inputOrder do wait()
inputOrder[i]["Tool"] = Pre[i - 1]
if i == 1 then
inputOrder["Tool"] = Child
end
end
``````

Thank you so much!

2 Likes