title: How to Filter/Search List in Unity
body: <p>I am trying to think of a way to filter a list of buttons that I dynamically create, based on values looped through from the SQlite DB. Each button is tagged with a student name and there could be a large number of buttons, hence the need to filter the buttons.</p>
  
  <p>I create my buttons as so:</p>
  
  <pre><code>public RectTransform GridWithNameElements;
  public GameObject StudentNamePrefabButton;
  
  while (reader.Read())
              {
                  //create a new button object and use the prefab button to make sure spacing etc is correct
                  goButton = (GameObject)Instantiate(StudentNamePrefabButton);
                  //set the parent of the button
                  goButton.transform.SetParent(GridWithNameElements, false);
                  goButton.transform.localScale = new Vector3(1, 1, 1);
                  //set the text of the button. Array value is 0 as the student name is always at position 0 on each iteration
                  goButton.GetComponentsInChildren&lt;Text&gt;()[0].text = reader["fullName"].ToString()+" | "+ reader["studentNumber"].ToString();
                  goButton.name = reader["studentID"].ToString();
  
                  Button tempButton = goButton.GetComponent&lt;Button&gt;();
                  int tempInt = i;
  
                  tempButton.onClick.AddListener(() =&gt; ButtonClicked(tempInt));
  
                  i++;
  
                  Debug.Log(goButton.name);
              }
  </code></pre>
  
  <p>Then I created an input field and attached a script to the <code>onValueChanged</code> in the input field and attempted to write a script.</p>
  
  <pre><code>//This method is called when the student attempts to search for their own name when taking the individual quiz
  public void SearchExistingStudentName()
  {
  
      //Get the name entered from the text field
      string student_name = searchExistingStudentNameInput.text;
  
      //Add names that exist to the new list
      List&lt;string&gt; names = new List&lt;string&gt;();
      names.Clear();
      //sets an id to the onclick listener of newly created buttons
      int x = 0;
  
      //if a new button object exists and the name was entered and then removed, clear it from the list and remove the created button
      if (student_name == "")
      {
          //Clear the filtered names List
          names.Clear();
          x = 0;
          //Destroy the create filter buttons if the user clears the text area
          GameObject[] objects = GameObject.FindGameObjectsWithTag("filterButton");
          //loop through the buttons that share the tag "filterButton"
          for (int count = 0; count &lt; objects.Length; count++)
          {
              Destroy(objects[count]);
  
              Debug.Log("Number of objects to be deleted " + objects.Length);
          }
  
          //Loop through and show all children 
          foreach (Transform child in GridWithNameElements)
          {
              child.gameObject.SetActive(true);
          } 
      }
      else if (student_name != "")
      {
          int count = 0;
          int filteredNameCount = 0;
          int filteredIDCount = 1;
          //loop through the list of buttons with student names
          for (int i = 0; i &lt; GridWithNameElements.childCount; i++)
          {
              Debug.Log("Children of grid "+GridWithNameElements.childCount);
              //Check if the user has typed their name with capitals or lowercase etc, and check the inputted value against names already in the list
              //If true, proceed 
              if (GridWithNameElements
                 .GetComponentsInChildren&lt;Text&gt;()[i].text.Contains(student_name) || GridWithNameElements
                 .GetComponentsInChildren&lt;Text&gt;()[i].text.ToLower().Contains(student_name) || GridWithNameElements
                 .GetComponentsInChildren&lt;Text&gt;()[i].text.ToUpper().Contains(student_name))
              {
  
                  //If the name entered contains letters found in the parent GridWithNameElements, then add them to the list array and their name value (unique id)
                  names.Add(GridWithNameElements.GetComponentsInChildren&lt;Text&gt;()[i].text.Replace(@"[", string.Empty).Replace(@"]", string.Empty));
                  names.Add(GridWithNameElements.GetChild(i).name); //this is the unique id of the student
  
                  Debug.Log("Number of items in filtered names list " + names.Count);
  
                  //Loop through and hide all children and hide them
                  if (count == 0)
                  {
                      foreach (Transform child in GridWithNameElements)
                      {
                          child.gameObject.SetActive(false);
                      }
                  }
  
                  count++;
  
                  //Then create a button that represents a name added to the names List
                  newButton = (GameObject)Instantiate(StudentNamePrefabButton);
                  //set the parent of the button
                  newButton.transform.SetParent(GridWithNameElements, false);
                  newButton.transform.localScale = new Vector3(1, 1, 1);
                  //set the text of the button. Array value is 0 as the student name is always at position 0 on each iteration
                  newButton.GetComponentsInChildren&lt;Text&gt;()[filteredNameCount].text = names[filteredNameCount].ToString();
                  newButton.name = names[filteredIDCount].ToString().Trim();
                  newButton.tag = "filterButton";
  
                  filteredNameCount++;
                  filteredIDCount++;
  
  
                  //Then add a click listener to the button
                  Button tempButton = newButton.GetComponent&lt;Button&gt;();
                  int tempInt = x;
  
                  tempButton.onClick.AddListener(() =&gt; ButtonClicked(tempInt));
  
                  x++;
  
                  // Debug.Log("Student Unique ID " + newButton.name);
  
  
              }   
          }
          count = 0;
      }       
  }
  </code></pre>
  
  <p>I was hoping to simply Loop through all list items, and hide those that don't match the search query. However, at the moment, my loop is wrong, as I get an out of bounds exception (which I think is to do with adding a new child element dynamically when making a search). I see this in the console log, however, the program executes as expected (so this is a problem, but currently not the biggest).</p>
  
  <p>I am hiding the original list and showing the new list based on matching criteria.</p>
  
  <p>However, I am only ever returning one possible name, rather than a bunch of possible choices. For example, if I had the name Ben Jones and Bob Dylan, based on my code at the moment, I am only ever able to return Ben Jones and never Bob Dylan.</p>
  
  <p>I feel like I am going the wrong way around doing this because I want something similar to <a href="https://www.w3schools.com/howto/howto_js_filter_lists.asp" rel="nofollow noreferrer">this</a>, and unable to recreate it. I am trying to figure out, however, if I am heading in the right direction or not.</p>
  
  <p>UPDATE</p>
  
  <p>I think I have found the reason for the <code>IndexOutOfRangeException: Array index is out of range.</code> It is because whenever I type a letter, it is calling the <code>SearchExistingStudentName()</code> method. This means that as long as the letter typed is found within one of the names, it is added to list - only the letter. This is why I can only return one name, rather than a list of possible names. Therefore I think the if statement needs amending, which I am trying to look into now.</p>
  
  <p>I have managed to narrow down the array exception in the code to this section:</p>
  
  <pre><code>//Loop through and hide all children and hide them
  if (count == 0)
  {
  foreach (Transform child in GridWithNameElements)
    {
  child.gameObject.SetActive(false);
    }
  }
  
  count++;
  
  //Then create a button that represents a name added to the names List
  newButton = (GameObject)Instantiate(StudentNamePrefabButton);
  //set the parent of the button
  newButton.transform.SetParent(GridWithNameElements, false);
  newButton.transform.localScale = new Vector3(1, 1, 1);
  //set the text of the button. Array value is 0 as the student name is always at position 0 on each iteration
  newButton.GetComponentsInChildren&lt;Text&gt;()[filteredNameCount].text = names[filteredNameCount].ToString();
  newButton.name = names[filteredIDCount].ToString().Trim();
                      newButton.tag = "filterButton";
  
  filteredNameCount++;
  filteredIDCount++;
  </code></pre>