Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

[SOLVED]New list at Runtime

Discussion in 'Scripting' started by dcamod, Nov 8, 2019.

  1. dcamod

    dcamod

    Joined:
    Oct 29, 2019
    Posts:
    19
    Hello all. I was just wondering how I should go about creating a button that when activated creates a new unique list every time. I am trying to make a button that creates a new list with the name that the user inputs. I have a button that allows user text input but that is as far as I got before I became confused. Lists and arrays only have the name you declared and I cannot input a string as their name.
     
  2. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    You can have all sorts of things, an array of lists, a dictionary<string, List<MyType>> (name to array/list)

    When you click the button you make a list, "with the name that the user inputs" I take as the name of the list, not an entry in the list.

    The first thing is you need to send some function the name you want, you said you already got that, good.

    what you'll want to do next is create the list you want and do what ever with it, then you add it to the collection, if you need the lists to be named you can use the dictionary I suggested or if you just wanna keep them seperated by index just stuff it in a list of lists/ array of arrays.

    Code (CSharp):
    1. Dictionary<string, List<string>> listMaster;
    2.  
    3. public void CreateList(string listName){
    4.  
    5. List<string> list = new List<string>(); //create new list
    6. list.Add("First entry");
    7. list.Add("Another entry");
    8. listMaster.Add(listName, list); //add list to dictionary
    9. }
    basically..
    you need to do some sanity checks and initialization, lookup how to use dictionaries if you're not familiar with them.
     
    dcamod likes this.
  3. dcamod

    dcamod

    Joined:
    Oct 29, 2019
    Posts:
    19
    Thanks that is exactly what I was looking for. I will go and try it out now. I read a little about dictionaries but was not sure if it was the best/only approach. Your reply was 100 times clearer than the tutorials I read and forums in other places. That is rare and I am very grateful for that.
     
    SparrowGS likes this.
  4. dcamod

    dcamod

    Joined:
    Oct 29, 2019
    Posts:
    19
    Okay the code has no errors, but I am confused about how to get it to work with what I have. I guess I'll just show what I have been doing so you can see what mess I have created and hopefully someone can help me understand why this is not working. I am totally new to c# and have only ever used GameMaker:Studio to program in. I think I am just not understanding some fundamentals in c#.
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class NameList : MonoBehaviour
    7. {
    8.     public InputField iField;
    9.     public string iField_name;
    10.  
    11.     Dictionary<string, List<string>> listMaster;
    12.  
    13.     public void CreateList(string listName)
    14.     {
    15.         List<string> list = new List<string>();
    16.         iField_name = iField.text;
    17.         list.Add(iField_name);
    18.         listMaster.Add(listName, list);
    19.         Debug.Log(listMaster);
    20.         Debug.Log(iField_name);
    21.     }
    So I have a button with this code attached to it. When I click the button an input field appears and allows text input. I tried Debug.Log(listMaster) as you can see but it is returning nothing in the console. I assume I am trying to access it incorrectly. iField_Name also does not appear in the console either no Idea why unless it needs something to initialize the function. I think CreateList is a function but how do I call it? I tried this code below right underneath the above code in the script but got a null reference exception when I ran it.
    Code (CSharp):
    1. public void Update()
    2.     {
    3.         CreateList("");
    4.         Debug.Log(iField_name);
    5.     }
    So if you are looking at this thinking wow he is lost...yeah I am. I am just jumping into c# and learning as I go. I appreciate any help, and believe me I am not just waiting on an answer. I am trying to figure this out on my own as I type this out. Again, I appreciate anything anyone has to offer greatly.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class NameList : MonoBehaviour
    7. {
    8.     public InputField iField;
    9.     public string iField_name;
    10.  
    11.     Dictionary<string, List<string>> listMaster;
    12.  
    13.     public void CreateList(string listName)
    14.     {
    15.         List<string> list = new List<string>();
    16.         iField_name = iField.text;
    17.         list.Add(iField_name);
    18.         listMaster.Add(listName, list);
    19.         Debug.Log(listMaster);
    20.         Debug.Log(iField_name);
    21.     }
    22.     public void Update()
    23.     {
    24.         CreateList("");
    25.         Debug.Log(iField_name);
    26.     }
    27.      [B]//My Original Button Code:[/B]
    28.     /*public List<string> MasterList = new List<string>();
    29.     public void Start()
    30.     {
    31.         iField_name = iField.text;
    32.         MasterList.Add(iField_name);
    33.         Debug.Log(iField_name);
    34.     }
    35.  
    36.     public void Update()
    37.     {
    38.         iField_name = iField.text;
    39.         MasterList.Insert(0 , iField_name);
    40.         if (MasterList[0] == iField_name){ Debug.Log("hey"); }
    41.         Debug.Log(iField_name);
    42.     }*/
    43. }
     
  5. DaDonik

    DaDonik

    Joined:
    Jun 17, 2013
    Posts:
    258
    Seems to be fine, all you have fogotten is to actually create the dictionary.
    You said "I have a dictionary named listMaster", but that is only an empty reference (i.e. It is null).

    Since you only want one listMaster, we add another method to the NameList class and we use
    Unity's Awake method for that. It is guaranteed to be only executed exactly once in the lifetime of
    NameList, which is what we need.

    Just put this alongside your Update method.
    Code (CSharp):
    1. private void Awake()
    2. {
    3.     listMaster = new Dictionary<string, List<string>>();
    4. }
    Note that the constructor, which we called with new, takes an optional parameter.
    It is the initial capacity and should be set to a value you think will never be reached.
    It's not a hard limit, but the Dictionary will make sure that it can fit the specified capacity.
    If you need more space, the dictionary will automatically resize itself, but that takes time
    and time is frames per second :D

    Make sure to bookmark this link. Incredibly useful to know what happens and when.
     
    dcamod likes this.
  6. dcamod

    dcamod

    Joined:
    Oct 29, 2019
    Posts:
    19
    Well that's very helpful I tried this and it did work, but I am not generating a new list with the name of the input. I am just changing the name of the list. I am receiving and error "An item with the same Key has already been added.Key"
    I believe that I am only creating one list instead of a new one every time I enter a new text input and I do not know how to verify this.


    Here is what I have now.

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6.  
    7. public class NameList : MonoBehaviour
    8. {
    9.     public InputField iField;
    10.     public string iField_name;
    11.  
    12.     //Create Dictionary
    13.     Dictionary<string, List<string>> listMaster;
    14.  
    15.     //Initialize Dictionary
    16.     private void Awake()
    17.     {
    18.         listMaster = new Dictionary<string, List<string>>(100);
    19.     }
    20.  
    21.     private void CreateList(string listName)
    22.     {
    23.         //listMaster = new Dictionary<string, List<string>>(100);//100 is more than the max amount of lists I expect.
    24.  
    25.         List<string> list = new List<string>();
    26.         listName = iField.text;
    27.         listMaster.Add(listName, list);
    28.         Debug.Log(listMaster);
    29.         Debug.Log(listName);
    30.     }
    31.  
    32.  
    33.     private void Update()
    34.     {
    35.         CreateList("");
    36.     }
    37.  
    38. }
    39.  
    40.  


    Edit: I have been working on it and this is what it looks like now. It still does not seem to work the way I would like. It just replaces the listName string but does not add a new list.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6.  
    7. public class NameList : MonoBehaviour
    8. {
    9.     public InputField iField;
    10.     public string iField_name;
    11.  
    12.  
    13.  
    14.     private void CreateList(string listName)
    15.     {
    16.         Dictionary<string, List<string>> listMaster = new Dictionary<string, List<string>>();
    17.         listName = iField.text;
    18.  
    19.         #region List Check
    20.        
    21.         var IO = listMaster.ContainsKey(listName);
    22.         if (IO) { return; }
    23.         else { listMaster.Add(listName, new List<string>()); }
    24.         #endregion
    25.  
    26.         foreach (KeyValuePair<string, List<string>> pair in listMaster)
    27.         {
    28.             Debug.Log(pair.Key);
    29.             Debug.Log(pair.Value);
    30.         }
    31.     }
    32.  
    33.     private void Update()
    34.     {
    35.         CreateList("");
    36.     }
    37.    
    38. }
     
    Last edited: Nov 13, 2019
  7. DaDonik

    DaDonik

    Joined:
    Jun 17, 2013
    Posts:
    258
    In your first code you are basically trying to add a new list with the same name over and over again.
    So as long as the text input field does not change, the dictionary will tell you "An item with the same Key has already been added.". Remember that the Update() method is called very often, possibly hundreds of times per second...
    Apart from that, the code should do exactly what you want.

    Your second code is plain wrong, since you are creating the dictionary every time you create a list.
    Which means that you will never be able to have a dictionary with more than one list, because you
    are literally replacing the dictionary every time.

    So we will just forget that and adjust the first code so that it works 'better' (TM).
    It's not tested, but it should work. Even though there are some things bad about this code, but that might
    be too much for now.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.UI;
    5.  
    6. public class NameList : MonoBehaviour
    7. {
    8.     private Dictionary<string, List<string>> listMaster;
    9.    
    10.     public InputField iField; // this is currently not used.
    11.     public string iField_name; // this, too.
    12.    
    13.     private void Awake()
    14.     {
    15.         listMaster = new Dictionary<string, List<string>>(100);
    16.     }
    17.  
    18.     private void CreateList(string listName)
    19.     {
    20.         if (listMaster.ContainsKey(listName))
    21.         {
    22.             Debug.Log("A list named: '" + listName + "' does already exist!");
    23.             return;
    24.         }
    25.  
    26.         listMaster.Add(listName, new List<string>());
    27.         Debug.Log("A list named: '" + listName + "' was added.");
    28.     }
    29.    
    30.     private void Update()
    31.     {
    32.         CreateList("");
    33.     }
    34. }
     
    dcamod likes this.
  8. dcamod

    dcamod

    Joined:
    Oct 29, 2019
    Posts:
    19
    Thank you very much. I actually had this figured out last night at about two thirty in the morning and was going to post an update today. I worked all day on this starting at 11 A.M. watching tutorials on the basics of the c#, searching the web for help, and just staring at syntax I had no clue about. Everything is similar except the Debug.Log bit and the list check region. Your version is way better. I used unnessesary variables to check that the list is added to the dictionary. I have erased unnecessary parts. I will post my version of what I did so people can see how I worked it out also and I will edit it for myself because yours is much cleaner than mine. I cannot thank you both enough for the assistance. You did not have to help with such a simple question. Yesterday was kind of a trial by fire deal.

    EDIT: This is What I ended up with last night.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using System;
    4. using UnityEngine;
    5. using UnityEngine.UI;
    6.  
    7. public class NameList : MonoBehaviour
    8. {
    9.     public InputField iField;
    10.     public string iField_name;
    11.     Dictionary<string, List<string>> listMaster;
    12.  
    13.     private void Awake()
    14.     {
    15.         listMaster = new Dictionary<string, List<string>>();
    16.     }
    17.  
    18.     private void CreateList(string listName)
    19.     {
    20.         listName = iField.text;
    21.  
    22.         #region List Check
    23.        
    24.         var IO = listMaster.ContainsKey(listName);
    25.         if (IO) { return; }
    26.         else { listMaster.Add(listName, new List<string>()); }
    27.         #endregion
    28.  
    29.         foreach (KeyValuePair<string, List<string>> pair in listMaster)
    30.         {
    31.             Debug.Log(pair.Key);
    32.         }
    33.     }
    34.  
    35.     private void Update()
    36.     {
    37.         CreateList("");
    38.     }
    39.    
    40. }
     
    Last edited: Nov 13, 2019
  9. DaDonik

    DaDonik

    Joined:
    Jun 17, 2013
    Posts:
    258
    Trial by fire...sounds like game dev to me :D

    Glad you figured it out. Just keep going!