Log in to vote

About Mixed Tables, and my table which is not a mixed table but throws that error?

Asked by 7 days ago

Greetings everyone. Directly to the point, I am trying to save a table with DataStore and I am getting this error:

Cannot convert mixed or non-array tables: keys must be strings

Here is my code. (NOTE: It's translated for you to understand better, but you can be sure language is not the problem causing this error.)

local ArmyFolder = game.Workspace.Armies
for a, b in pairs(ArmyFolder:GetChildren())
    local ArmyID = b.Settings["ArmyID"].Value
    Armies[ArmyID] = {}
    Armies[ArmyID]["StartX"] = b.Settings["Start"].Value.X
    Armies[ArmyID]["StartY"] = b.Settings["Start"].Value.Y
    Armies[ArmyID]["StartZ"] = b.Settings["Start"].Value.Z
    Armies[ArmyID]["EndX"] = b.Settings["End"].Value.X
    Armies[ArmyID]["EndY"] = b.Settings["End"].Value.Y
    Armies[ArmyID]["EndZ"] = b.Settings["End"].Value.Z
    Armies[ArmyID]["StartTime"] = b.Settings["StartTime"].Value

I spent hours(Literally hours, like 7-8 hours) looking for the problem and trying every combination I could try... I really need help. Thanks already!

I don't see anything about datastore in there. It might be better to find a minimal repro of the problem with real code, and post that. Brouhahaha 5 — 7d

2 answers

Log in to vote
Answered by 7 days ago

You actually can put tables in tables:

> ds=game:GetService("DataStoreService")
> d = ds:GetDataStore("Debug")
> d:SetAsync("debug", {1,{hi=2, there=3},4})
> t = d:GetAsync("debug")
> print(unpack(t))
1 table: 3402BC9C 4
> print(t[2].hi, t[2].there)
2 3

The problem is that you aren't allowed to have a list with holes in it (that's what it means by "non-array tables"). Actually, it won't error for that (I tried it - you lose information, but it won't error), but it will error if you have integer keys without there being a key in the first slot. ex it will error if you try to save t = {}; t[2] = 2

Note: RemoteEvents and RemoteFunctions have the same limitation

To fix this, you need to store a list of armies, not a dictionary of their ID to the values. That is:

local ArmyFolder = game.Workspace.Armies
for a, b in pairs(ArmyFolder:GetChildren()) do
    local army = {}
    table.insert(Armies, army)
    army["ID"] = b.Settings["ArmyID"].Value
    army["StartX"] = b.Settings["Start"].Value.X
    army["StartY"] = b.Settings["Start"].Value.Y
    army["StartZ"] = b.Settings["Start"].Value.Z
    army["EndX"] = b.Settings["End"].Value.X
    army["EndY"] = b.Settings["End"].Value.Y
    army["EndZ"] = b.Settings["End"].Value.Z
    army["StartTime"] = b.Settings["StartTime"].Value

Note: you can also do army.ID = (same for all string keys).

Thanks for answer and sorry for late checking. I got what you are saying but there will be around 40-50 armies. When I load armies, I will need to load their start end and starttime values as fast as possible. If I add them to a table from 1 to ArmyCount, it would make me to search for those armies. If we say we have 40 armies, it would need to check a total of 460 times....(Will Continue) superalp1111 348 — 1d
...So that would add a penalty I guess... Isn't there a wa- okay I got it, What if I add army into Armies with ID as key and fill the blank ones? Like, if there is no Armies[3] if I fill that with an empty table would it work? superalp1111 348 — 1d
Log in to vote
Answered by 7 days ago

Well, first of all I've forgot to add my SetAsync function into the code. Sorry about that. Secondly, I've fixed it. I am not deleting this question because I spent over seven hours on this problem and do not want anyone else to spend another seven hours on this type of problem. Just one basic sentence: You can't save tables inside tables.

Answer this question