Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by 6 years 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
end

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!

0
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 27 — 6y

2 answers

Log in to vote
1
Answered by 6 years 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
end

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

0
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 662 — 6y
0
...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 662 — 6y
0
I don't understand why you'd need to check 460 times. Why not iterate over the entire list of armies periodically (even every frame (30x/sec)) and update their position? As for your 2nd comment, you could do that, but it would be slower. If you commonly need to look up an army by ID, you can use a dictionary (ID as key, as you say), and simply use `pairs` to iterate over it. ... chess123mate 5873 — 6y
0
... You wouldn't be able to use that same dictionary in the datastore, but you can copy over the values whenever you need to save. chess123mate 5873 — 6y
Ad
Log in to vote
0
Answered by 6 years 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