Iterate through Generic List

Hey all,

I’m working on a little project to practice both my narrative design skills, as well as my Unity basics. Without explaining the entire thing, I can say that what I want is for the player to be able to collects phrases (Strings) to form a piece of text. Eventually, I want them to be able to remove or rearrange the phrases as well, but I’m taking it one step at a time.

After doing a bit of research, I figured using a Generic List was best. What I want to do is this: add items (Strings) to the List, then iterate through that List and spawn a GUI.Button for each item in the List (each button having its own space).

I came up with this (I work in Javascript):

import System.Collections.Generic;

var phraseList = new List.<String>();

function OnGUI () {

		phraseList.ForEach (
			function() {
				if (GUI.Button (Rect (100, 20 * phraseList.Item, 200, 20), "button")) {
					Debug.Log ("Box #" + phraseList.Item + " is working");
				}
			}
		);
		
}

function Update () {
	if (Input.GetKeyUp ("z")) {
		phraseList.Add("Test string 1");
		phraseList.Add("Test string 2");
		phraseList.Add("Test string 3");
		phraseList.ForEach (print);
		
	}
}

But I get the following error message: “The property ‘System.Collections.Generic.List.Item’ cannot be used without parameters.”

What kind of property do I need for “the current item”, if you will? I hope you guys can help a beginner out!

Thanks in advance,

Veliremus

2 Answers

2

After receiving two answers by @syclamoth and @Erich5h5, I managed to get the generic List working in Javascript.

Javascript (solution provided by Eric5h5):


import System.Collections.Generic;

var phraseList = new List.<String>();

function OnGUI () {
	
	var i : int = 0;
	for (str in phraseList) {
		if (GUI.Button (Rect (100, 20 * i, 200, 20), str)) {
			Debug.Log ("Box #" + i + " is working!");
		}
	i++;
	}

}
	
function Update () {
	if (Input.GetKeyUp ("z")) {
		phraseList.Add("Test string 1");
		phraseList.Add("Test string 2");
		phraseList.Add("Test string 3");
		
	}

}

C# (solution provided by syclamoth):


using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Bluh : MonoBehaviour {

List<String> phraseList = new List<String>();

void OnGUI() {
    int i = 0;
    foreach(String str in phraseList)
    {
       if(GUI.Button (Rect (100, 20 * i, 200, 20), str)) {
         Debug.Log("Box #" + i + " is working");
       }
       i++;
    }
}
void Update () {
    if(Input.GetKeyUp("z"))
    {
       phraseList.Add("Test string 1");
       phraseList.Add("Test string 2");
       phraseList.Add("Test string 3");
       foreach(String str in phraseList)
       {
         Debug.Log(str);
       }
    }
}
}

Thank you both very much!

You’re on the right track here, but I don’t quite know if the syntax is right. Personally, I work in C# exclusively (I find javascript just unendingly frustrating because it lacks this kind of functionality)- As far as I can tell, Javascript does not support generic lists the way you want them. I would recommend porting your script to C#- it doesn’t take very long, and learning to program in it will be worthwhile in the long-term as well. For the script you posted there, the translation would be somthing along the lines of:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Bluh : MonoBehaviour {

List<String> phraseList = new List<String>();

void OnGUI() {
	int i = 0;
	foreach(String str in phraseList)
	{
		if(GUI.Button (Rect (100, 20 * i, 200, 20), str)) {
			Debug.Log("Box #" + i + " is working");
		}
		i++;
	}
}
void Update () {
	if(Input.GetKeyUp("z"))
	{
		phraseList.Add("Test string 1");
		phraseList.Add("Test string 2");
		phraseList.Add("Test string 3");
		foreach(String str in phraseList)
		{
			Debug.Log(str);
		}
	}
}
}

Thanks for your answer! However, as a beginner, I've really learned everything in Javascript, and I don't know if I want to switch to C# just yet. That said, your code reminded me of the following code I used for Arrays: for (var i : int = 0; i < tempArray.length; i++) { //Iterate through array and print array content as buttons if (GUI.Button (Rect (100, 20 * i, 200, 20), "String: " + tempArray*)) {* _ //tempArray.Remove*;*_ _* }*_ _*}*_ Can something like that be adopted for the Generic List?

Or maybe this is of use, I don't really understand it myself, but hey... :P http://forum.unity3d.com/threads/79760-How-to-use-generics-in-unity-javascript

I still say you are making things unnecessarily difficult for yourself by denying yourself all the useful features of C#, but that post provides a functional implementation of generics in js.

Maybe I will switch to C# then. Thanks for your help, in any case. I'll convert my script to C# and see if works. (Why aren't there notifications for comments?)

@syclamoth: JS doesn't lack that kind of functionality at all. The script would identical in JS, substituting JS syntax of course. i.e., instead of foreach, use for (str in phraseList). In most cases there's no reason to use C# unless you happen to prefer it.