Get first/second item in a table

[1] = Responses = {['Hello'] = 3, ['Goodbye'] = 4}},

print(v.Responses) -- prints a table
print(v.Responses[1]) -- prints nil

To me, v.Responses[1] should print ‘Hello’, v.Responses[2] should print ‘Goodbye’. But it prints nil

1 Like

I’m not quite sure what you’re trying to do, but if Responses is {['Hello'] = 3, ['Goodbye'] = 4} and you want Hello to be retrieved when you index Responses with 1, then you might have to create a new table.

local v = {Responses = {}}
local n = 0
for index,value in pairs(Responses) do
      n = n + 1
      v.Responses[n] = index
end

(Responses is your Responses table, v is just where I’m storing it)

2 Likes

I want to be able to set a textlabel to each one

Choice1.Text = v.Responses[1] -- Would be Hello
Choice2.Text = v.Responses[2] -- Would be Goodbye

You can use this code for that.

local Responses = {['Hello'] = 3, ['Goodbye'] = 4}

local v = {Responses = {}}
local n = 0

for index,value in pairs(Responses) do
	n = n + 1
	v.Responses[n] = index
end

print(v.Responses[1])

Wait, if you are trying to get “Hello” and “Goodbye” as an output, then shouldn’t you use print(v.Responses["Hello"] or print(v.Responses["Goodbye"]?

1 Like

I can’t do that as the responses are part of a larger reference of code, which can’t be touched. I need to purely just reference them. Not insert things into tables, etc.

Can’t do that, as what if I had

[1] = Responses = {['Hello'] = 3, ['Goodbye'] = 4}},
[2] = Responses = {['Heyo'] = 3, ['Ciao'] = 4}},

Choice1.Text = 'Hello'
Choice2.Text = 'Goodbye'

What happens if I want to reference the second table in the array?

1 Like

Just to clarify, in that example, doing v.Responses[1] would return ‘Hello’, v.Responses[2] would return ‘Goodbye’, and doing v.Responses[3] would return ‘Heyo’?

This is my dialogue data for example

['Pizza Chef'] = {
		Color = Color3.fromRGB(197, 88, 88),
		Messages = {
			[1] = {Msg = 'Hello! Welcome to the Pizzeria!', Type = 'Dialogue'},
			[2] = {Msg = 'Feel free to have a slice with friends or make your own pizzas in the kitchen', Type = 'Question', Responses = {['How can I make my own Pizzas?'] = 3, ['Goodbye'] = 4}},
			[3] = {Msg = 'Head over to the door on the right!', Type = 'Farewell'},
			[4] = {Msg = 'Ciao!', Type = 'Farewell'},
 		}
	},

Look at the [2] column

print(v.Msg) -- prints 'Feel free to have a slice with friends or make your own pizzas in the kitchen'
print(v.Responses) -- prints a table
print(v.Responses[1]) -- prints nil

I want

print(v.Responses[1])

to print ‘How can I make my own Pizzas?’

Oh ok, well you can do

Responses = {'How can i make my own Pizzas?'}

I’m not sure why you’re assigining 3 and 4 to the dialogue though?

No :man_facepalming:

Responses = {['How can I make my own Pizzas?'] = 3, ['Goodbye'] = 4}

3 means I’d go to the third section in the array if I chose that choice. 4 would go to the 4th section in the array.

NOTHING in this

['Pizza Chef'] = {
		Color = Color3.fromRGB(197, 88, 88),
		Messages = {
			[1] = {Msg = 'Hello! Welcome to the Pizzeria!', Type = 'Dialogue'},
			[2] = {Msg = 'Feel free to have a slice with friends or make your own pizzas in the kitchen', Type = 'Question', Responses = {['How can I make my own Pizzas?'] = 3, ['Goodbye'] = 4}},
			[3] = {Msg = 'Head over to the door on the right!', Type = 'Farewell'},
			[4] = {Msg = 'Ciao!', Type = 'Farewell'},
 		}
	},

Can be changed. It has to stay EXACTLY as written. All I want to do is reference Responses and get the first and second item in the table. That’s it. No adding items to new tables, no changing tables around

local dialog = {['Pizza Chef'] = {
		Color = Color3.fromRGB(197, 88, 88),
		Messages = {
			[1] = {Msg = 'Hello! Welcome to the Pizzeria!', Type = 'Dialogue'},
			[2] = {Msg = 'Feel free to have a slice with friends or make your own pizzas in the kitchen', Type = 'Question', Responses = {['How can I make my own Pizzas?'] = 3, ['Goodbye'] = 4}},
			[3] = {Msg = 'Head over to the door on the right!', Type = 'Farewell'},
			[4] = {Msg = 'Ciao!', Type = 'Farewell'},
 		}
	},
}

local function getResponseByIndex(v,i)
	local responses = v.Responses
	local n = 0 
	
	for response,nextSection in pairs(responses) do
		n = n + 1

		if n == i then
			return response,nextSection
		end
	end
end

local v = dialog['Pizza Chef'].Messages[2]

print(v.Msg) --> Feel free to have a slice with friends or make your own pizzas in the kitchen

local text,nextSectionInArray = getResponseByIndex(v,1)

print(text) --> How can I make my own Pizzas?

The way it is currently set up you’d only be able to get the number if your index was the question (in your case it could be v.Responses['How can I make my own Pizzas?']. One solution that I think could work is to have all the responses become another table.

Here’s what I mean:

Responses = {
    { Response = ['How can I make my own Pizzas?'], Number = 3 }, 
    { Response = ['Goodbye'], Number = 4 }
}

print(Responses[1].Response) -- Should be: How can I make my own Pizzas?
print(Responses[1].Number) -- Should be: 3

Not sure if that is viable with the way your system is set up.

1 Like

You can also do:

local tab = {
	
	['Pizza Chef'] = {
		Color = Color3.fromRGB(197, 88, 88),
		Messages = {
			[1] = {Msg = 'Hello! Welcome to the Pizzeria!', Type = 'Dialogue'},
			[2] = {Msg = 'Feel free to have a slice with friends or make your own pizzas in the kitchen', Type = 'Question', Responses = {['How can I make my own Pizzas?'] = 3, ['Goodbye'] = 4}},
			[3] = {Msg = 'Head over to the door on the right!', Type = 'Farewell'},
			[4] = {Msg = 'Ciao!', Type = 'Farewell'},
 		}
	},
	
}


local Messages = tab["Pizza Chef"].Messages

for i = 1, #Messages, 1 do
	
	print(i)
	print(Messages[i].Msg) -- not nil
	print(Messages[i].Type) -- not nil
	
end

Edit here is the output:
TableOutput

1 Like

So given this data table:

	['Pizza Chef'] = {
		Color = Color3.fromRGB(197, 88, 88),
		Messages = {
			[1] = {
				Msg = 'Hello! Welcome to the Pizzeria!', 
				Type = 'Dialogue'
			},
			[2] = {
				Msg = 'Feel free to have a slice with friends or make your own pizzas in the kitchen', 
				Type = 'Question', 
				Responses = {
					['How can I make my own Pizzas?'] = 3, 
					['Goodbye'] = 4
				}
			},
			[3] = {
				Msg = 'Head over to the door on the right!', 
				Type = 'Farewell'
			},
			[4] = {
				Msg = 'Ciao!', 
				Type = 'Farewell'
			},
 		}
	},

Since you can’t change the Responses table to fit your needs, what you can do instead is remap from number to text with another table:

local NPCResponseMap = {
	['Pizza Chef'] = {
		[2] = {
			[1] = 'How can I make my own Pizzas?',
			[2] = 'Goodbye'
		}
	},
	-- other NPC's
}

Then, you will have to relocate to your question-oriented response map using the data used to get to your NPC’s question:

local Messages = _['Pizza Chef'].Messages

for i, v in ipairs(Messages) do
	print(v.Msg) -- message text

	
	if v.Type == "Question" then
		local map = NPCResponseMap['Pizza Chef'][i]
		print(v.Responses) -- a table
		print(map[1]) -- response text
		print(v.Responses[map[1]]) -- message ID

		print(Messages[v.Responses[map[1]]].Msg) -- "Head over to that door"
	end
end

Of course, this is a very roundabout way to go about it, you’re basically duplicating an entire data structure to get what you want, and you would have to guarantee that the text in the response map is the exact same as the text index from Responses, which is a pain and much more prone to error.


Instead, you should try @NicholasY4815’s idea and change the Responses table so that the text you want is paired with the reference to the next message in another table.
This is because the only way to get the text is by already knowing what it is beforehand, because you are indexing by that text.
I would do something like this for the Responses table:

Responses = {
	[1] = {Text = 'How can I make my own Pizzas?', Ref = 3},
	[2] = {Text = 'Goodbye', Ref = 4}
}

Then you can get both the response text and message reference through Responses[1]:

local Messages = _['Pizza Chef'].Messages

for i, v in ipairs(Messages) do
	print(v.Msg) -- message text

	if v.Type == "Question" then
		print(v.Responses) -- a table
		print(v.Responses[1]) -- another table

		print(v.Responses[1].Text) -- response text
		print(v.Responses[1].Ref) -- message ID

		print(Messages[v.Responses[1].Ref].Msg) -- "Head over to that door"
	end
end

If you have a system where you use the dialog’s text to reference the next message, you could, say, attach an IntValue under the response’s gui element with a reference to the response number.