So, like you say, the problem is that Unity Script isn’t Javascript - they’ve tried to make some things look the same, but dictionaries are a different matter.
You want to use native arrays with defined types or Lists if you want the size to be mutable, so what you are after is:
import System.Collections.Generic;
var myDictionary = new Dictionary.<String, List.<String>>();
Now no problem to access the entries if they existed:
x["2"].Add("dos");
print(x["1"][0]);
However the List. will not have been initialized for new keys. To the first time:
if(!x.ContainsKey("2")) x["2"] = new List.<String>();
I find this annoying all the time
So I’ve written a C# override to dictionary that handles the initialization. You can use this from JavaScript if you put the C# in Plugins and don’t use it in a JavaScript Plugin.
#Index.cs
using System;
using System.Collections.Generic;
public class DefaultDictionary<TK, TR> : Dictionary<TK, TR>
{
public new virtual TR this[TK index]
{
get
{
if (ContainsKey(index))
{
return base[index];
}
return default(TR);
}
set
{
base[index] = value;
}
}
public T Get<T>(TK index) where T : TR
{
return (T)this[index];
}
}
public class Index<TK, TR> : DefaultDictionary<TK, TR> where TR : new()
{
public virtual TR Create()
{
return new TR();
}
public override TR this[TK index]
{
get
{
TR value;
if (TryGetValue(index, out value))
{
return value;
}
var ret = Create();
base[index] = ret;
return ret;
}
set
{
base[index] = value;
}
}
}
You use this by defining an:
var x = new Index.<String, List.<String>>();
This you can use without initializing anything yourself:
x["Whatever"].Add("It doesn't matter");
print(x["Whatever"][0]);
The default dictionary is useful when it’s a value type or you want a null rather than an exception if the dictionary doesn’t have the key:
var d = new DefaultDictionary.<String, boolean>();
print(d["someMissingKey"]); //Prints false rather than throwing an exception
Oh btw : x["2"] = new List.<String>(["one", "two"]);
– whydoidoitincredibly generous answer-article (worth be on gems?)
– FattieThanks for the awesome reply whydoidoit! It seems like I need to look a bit more into what bits of Mono is revealed through UnityScript and throw away a lot of preconceptions.
– bundyAs a note to anyone that tries whydoidoit's code in Javascript, you need to add a space at the end of the List type within the Dictionary initialization: var myDictionary = new Dictionary.<String, List.<String>>(); to var myDictionary = new Dictionary.<String, List.<String> >(); Figured it out from here: http://forum.unity3d.com/threads/88055-Using-List-and-Dictionary-with-UnityScript?p=568733&viewfull=1#post568733
– bundyAh good point :) Yeah that'll do me for programming in an Answer box ;) Really you need to forget all the clever stuff you know about Javascript - because most of it either won't work, won't quite work or will work but be poor performing. Then there's all the extra stuff like defining classes etc etc - really a bunch of stuff to learn. I'd be programming JS for 6 months before starting with Unity, but my background is C# and I switched back to that eventually.
– whydoidoit