Iterating Enums in Unityscript using Lists rather than Arrays

Currently I am using Arrays in my Unityscript scripts because I did not know about Lists. Having read lots of people extol the virtues of Lists I want to try them in my new project. But I can’t find how to iterate over enums using them. For example I have this script. What would be the equivalent using Lists?

#pragma strict

enum Dna {nothing, quick, endurance, ......}

function GetRandomDna(vi_except : Dna) : Dna {
	var va_all_dna : Dna[];
	va_all_dna = Dna.GetValues(Dna);
	while(true) {
		var i : int = Random.Range(0,va_all_dna.length);
		if (va_all_dna[i] != vi_except) {
			break; // got one that is different to the exception
		}
	}
	return va_all_dna[i];
}

Lists are good when you have a variable sized container. I.e. you want to add/remove elements after the container has been created. An Enumeration cannot be added to/removed from, as it’s a static list of elements. I’m not sure why you want to use lists, other than for the sake of lists, but in that circumstance there is no reason to use lists, as arrays are faster(but less feature-rich, though that doesn’t matter for this use).

But for strictly educational purposes:

#pragma strict
import System.Collections.Generic;

enum Dna {nothing, quick, endurance, ......}

function GetRandomDna(vi_except : Dna) : Dna {
	var va_all_dna : List.<Dna> = new List.<Dna>();
	va_all_dna.AddRange(Dna.GetValues(Dna));
	while(true) {
		var i : int = Random.Range(0,va_all_dna.Count);
		if (va_all_dna[i] != vi_except) {
			break; // got one that is different to the exception
		}
	}
	return va_all_dna[i];
}

I don’t write in JS and didn’t test it, so please correct any silly mistakes.

Think of Lists as a much better version of the UnityScript Array class. It’s a dynamically resizable array, which lots of bonus features you can use: List<T> Class (System.Collections.Generic) | Microsoft Learn . While the examples there will be in C#, that is the same List as UnityScript with (Almost) the same features.

Thanks, Ntero, much appreciated.

  1. I had read that lists were much faster than arrays and arrays were deprecated, so thought I would use them. But perhaps Lists are only faster to make changes to the number of items within them.

  2. Any idea how why you get a downcast warning: “BCW0028: WARNING: Implicit downcast from ‘System.Array’ to ‘System.Collections.Generic.IEnumerable.’.” and how to remove it without using a pragma downcast?

1)Lists are faster than JavaScript’s Array(capital A) class. Which is a dynamic container(can be resized without emptying the contents) without any types within(everything is just Object). The C# equivalent is ArrayList. List. allows you to preserve types and runs faster/easier to use. System.Array ([ ] style creation) is faster still, even though both JS’s Array and List use it under the hood. It has less overhead and extra bounds checks that both JS’s Array and List have to perform.

To help clarify:
JS’s Array type: Dynamically sized, all base types (need to be casted to be used), slowest
List.: Dynamically sized, of shared type T(usable immediately without casting), faster than JS Array
Array [ ]: Fixed size on creation, does not require casting, faster than either dynamically sized container. Used by both List. and JS’s Array.

2)Cast it explicitly. What that is telling you is that you are casting from Array to IEnumerable. (A container of Dna objects that can be iterated across). But the cast is implicit(done behind the scenes without you telling it to in code), and when using #pragma strict, I’m going to guess it marks those as errors (unless you also do #pragma downcast). It’s a 100% valid cast, and so just manually do it instead of having it hidden.

Try:

va_all_dna.AddRange((IEnumerable.<Dna>)Dna.GetValues(Dna));

Although I would suggest adding Downcast, as much of .NET relies on interface inheritance and you are going to end up adding a TON of down casts and clutter up your code.

Awesome, thanks so much for your very clear explanations.