- Home /
Iterate through Generic Dictionary?
How does one iterate through a generic dictionary?
I could find example code in C#, but attempting to adapt it to UnityScript hasn't worked - I get the error Cannot convert 'Object' to 'System.Collections.Generic.KeyValuePair'.
#pragma strict
static function SetActive( inDict : Dictionary.<String,GameObject>, newState : boolean )
{
for(var cObj:KeyValuePair.<String,GameObject> in inDict)
cObj.Value.active = newState;
}
Answer by yoyo · Mar 08, 2011 at 09:33 PM
You can also iterate through the keys (or values) of a dictionary, which might simplify the code. The following samples compile, I haven't tried running them.
By key:
static function SetActive( inDict : Dictionary.<String,GameObject>, newState : boolean )
{
for(var cKey in inDict.Keys)
inDict[cKey].active = newState;
}
or by value:
static function SetActive( inDict : Dictionary.<String,GameObject>, newState : boolean )
{
for(var cObj in inDict.Values)
cObj.active = newState;
}
Awesome! With #pragma strict I found it necessary to change the fourth line to (cObj as GameObject).active = newState;
could you say "for(var cObj:GameObject in iDict.Values)"? (I'm not a javascript guy, so I'm making this up as I go along ...)
Answer by Waz · Jun 05, 2011 at 03:05 AM
The UnityScript foreach statement is not very helpful when you want to use static typing (which you should, it's faster) or generics like this. Instead, fall back to this slightly less pretty enumerator-based syntax:
for(var e=inDict.GetEnumerator(); e.MoveNext();)
e.Current.Value.active = newState;
or for clarity:
var e = inDict.GetEnumerator();
while (e.MoveNext())
e.Current.Value.active = newState;
Most importantly, this also works with #pragma strict
(which helps you ensure you're writing efficient code), and does not require #pragma downcast
.
The basic problem otherwise is that UnityScript's foreach only works with Object subclasses, whereas DictionatyEntry is a value type.
Thanks for this, it's precisely what I needed. A typesafe way to iterate over dictionary in JS without requiring #pragma downcasts everywhere.
This is definitely a better alternative than the accepted answer! Thanks!
Answer by Mike 3 · Mar 08, 2011 at 07:50 PM
Fairly odd, but this fixes it:
class Whatever
{
static function SetActive( inDict : Dictionary.<String,GameObject>, newState : boolean )
{
for(var cObj:KeyValuePair.<String,GameObject> in inDict)
cObj.Value.active = newState;
}
}
No clue why right now, but with the implicit class it just dies
Edit:
add in #pragma downcast It'll downcast it to the correct type then. Still no clue why
That does work, but I don't understand why either. I'm wrapping all the scripts in my utilities into a Utilities class, and now I get that DestroyImmediate isn't a member of Object. This is all very strange...
Edited the answer, still no clue but quicker (and more elegant) fix
Oh, the DestroyImmediate one I know. Object in js is mapped to System.Object for some bizarre reason. If you use GameObject.DestroyImmediate, it should fix that
Okay, it seems that if this function is in any class that is called by another class, then I get the "Cannot convert 'Object'..." error.
You'll probably need to use #pragma downcast to those too. This seems like a compiler error to be honest
Your answer
Follow this Question
Related Questions
C#, code stops loop prematurely 1 Answer
create object and add increment number to it's name 3 Answers
How do I loop my light animation is javascript? 1 Answer
How do I prevent audio from restarting if it's being asked to play again? 2 Answers
Ways to optimize this code? iterate through inventory 0 Answers