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. Dismiss Notice

Data Gap

Discussion in 'Scripting' started by natmaxex, Oct 15, 2021.

  1. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    how should i go about removing data gaps when I need to remove variables from arrays. What if I need to remove a game object from anywhere in an array.
    misingData2.PNG

    misingData.PNG

    misingData3.PNG

    I don't think this code is going to cut it.
    Code (CSharp):
    1. [SerializeField]
    2. private GameObject[] testObj;
    3.  
    4. // Start is called before the first frame update
    5. void Start()
    6. {
    7.     for(int i = 0; i < testObj.Length; i++){
    8.         Debug.Log(testObj[i].name);
    9.     }
    10. }
     
  2. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,913
    If you don't care about the order then just move the very last item over to the one you want to remove.

    And please, finish a C# tutorial.
     
    natmaxex likes this.
  3. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,895
    This code will throw an error should any of the index be null on the array. It's not particularly easy to remove elements from a specific index from an array either.

    You should use List<T> instead and walk through the array for any null references and remove them from the list. Alternatively, if these elements are part of a list, should they be destroyed they should be removed from the list at the same time.
     
    Bunny83 and natmaxex like this.
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,531
    It's not clear if you want to remove an item in the editor, in which case you can simply click on the item label at the front to select the element and press the "-" button at the bottom of the array view.

    If you talk about removeing an item at runtime through code, that's not possible at all since arrays have a fixed size and can not be resized. Yes, there is the System.Array.Resize method which lets you resize an array. However it actually creates a new array and copies the old elements over and replaces the old array in the variable you pass in by reference.

    If you want to remove or add elements at runtime, you should simply use a generic List instead. It has a Remove and a RemoveAt method. Remove let you remove a certain element that you pass to the method. This method will search for the first occurrence of that element and removes that. RemoveAt allows you to remove an element at a certain index.

    Internally a List also holds an array which usually has some spare elements that are unused. The list will automatically allocate a new larger array if it runs out of elements when you call Add. Removing elements will just close the gap automatically for you. So when you call remove on an element somewhere in the middle, it will automaticlaly move all following elements one up to close the gap. The list keeps track how many "actual" elements are in the list. This can be read out with the Count property. The Capacity is the actual size of the internal array. Though in 99% of all usecases you don't have or should not worry about the capacity.
     
  5. exiguous

    exiguous

    Joined:
    Nov 21, 2010
    Posts:
    1,749
    I quote Bunny here but this intended for op since Bunny probably knows this.
    When you know the approximate (or definite) size of the List it does not hurt to set the capacity via constructor. This saves your list from frequently allocating memory and copying elements. So for example you create a List with default constructor and then add 10k elements to it will increase the capacity several times (and cost time/"performance"). When you know you are going to add 10k elements set the initial capacity from the start and all your elements will fit in without the need of reorganization. This is also usefull for StringBuilder for example. Sure it's a one-time cost (at creation time) but every little matters, especially when it is so easily achieved ;).

    Another performance tip for List (as already hinted by Lurking-Ninja for arrays) is, when you don't depend on the order of objects in it, don't use RemoveAt since it will shift all elements behind the removed one. Instead copy the last element at the position of the element to be removed and remove the last one. This prevents (heavy) copying and can be neatly written into an extension method.

    So in general when you need to change the number of elements in an collection use a List.
     
    Bunny83 likes this.
  6. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    So you're saying this is the only way?
    Code (CSharp):
    1. for(int i = 0; i < testObj.Length; i++){
    2.         if(testObj[i]){
    3.             Debug.Log(testObj[i].name);
    4.         }
    5. }
     
  7. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,895
    Did you even read anything that we wrote?
     
    Joe-Censored and Bunny83 like this.
  8. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    How about this?
    Code (CSharp):
    1. [SerializeField]
    2. List<GameObject> testObj;
    3.  
    4. //removeObject and tell me about it
    5. public void RemoveObj(GameObject removeThis) {
    6.     if (testObj.Contains(removeThis)) {
    7.         testObj.Remove(removeThis);
    8.     }
    9.  
    10.     for (int i = 0; i < testObj.Count; i++)
    11.     {
    12.         Debug.Log(testObj[i].name);
    13.     }
    14. }
    And yes everyone is doing a good job at mocking and making fun of me. I am hurt.
     
    Last edited: Oct 15, 2021
  9. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,913
    Joe-Censored likes this.
  10. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,895
    Yes, removing the GameObject from the list before you destroy it is a reasonable way of avoiding missing references.

    Alternatively, if you need to clear out a list of empty references, you can iterate over the list backwards, such as this simple example I knocked up:
    Code (CSharp):
    1. public class MonobehaviourWithLists : MonoBehaviour
    2. {
    3.     public List<GameObject> listOfGameObjects = new List<GameObject>();
    4.  
    5.     [ContextMenu("Remove Empties")]
    6.     private void RemoveEmptyReferences()
    7.     {
    8.         for (int i = listOfGameObjects.Count - 1; i > -1; i--)
    9.         {
    10.             if (listOfGameObjects[i] == null) listOfGameObjects.RemoveAt(i);
    11.         }
    12.     }
    13. }
    Alternatively, alternatively, you could use linq and something like:
    listOfGameObjects = listOfGameObjects.Where(x => x != null).ToList();
    to reassign the list with a new list that doesn't have any missing references.
     
    Bunny83 and natmaxex like this.
  11. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    I added the if statement to check and see if the object is in the list before it tries and removes it so as not to throw an error and doesn't try and remove something that isn't there. but your right I might not need to do things like that.

    I know how C# works, I just need to touch upon a few things. I don't know everything and I'm not perfect.

    While your insults are painful I do appreciate the helpful documentation link, I look forward to looking it over.
     
    Last edited: Oct 16, 2021
  12. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    Thats an interesting way of using a for loop
    Code (CSharp):
    1. for (int i = listOfGameObjects.Count - 1; i > -1; i--)
     
  13. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,913
    Friendly off-topic advise: stop playing the victim and the martyr. No one is attacking you. Stating that you don't know something and directing you to resources so you can brush up on your knowledge is not an insult, it's a statement of perceived facts. No one thinks lesser of you because of your lack of knowledge. But I, and I think "we on these forums", think lesser of you because you're unnecessarily playing the victim and you refuse to learn.

    You're welcome.
     
    Last edited: Oct 16, 2021
    Kurt-Dekker, Bunny83 and hippocoder like this.
  14. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    I am not playing anything and trying to learn. I'm watching the video on c# and reading the documentation. plus I have been programming with unity since it first came out. I think the problem here is I'm insulted you keep saying I don't know how to program and I would like an apology and for everyone to stop saying I don't know how to program and instead only address the information I don't understand or need to learn.
    example: I don't know everything about lists your more than welcome to tell me I don't know how to use lists. and how to improve upon that skill.
    I'm sorry if I have been coming across as playing a victim, I will not do that anymore.
     
    Last edited: Oct 16, 2021
  15. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,913
    Please note that I said you don't really know C#, which shows over the recent posts you're making. I don't really know too much about your programming in general and I think I never mentioned it. And I will stop this here.
     
    hippocoder likes this.
  16. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    This has been stressful :C. I would like to go back to programming.

    In the documentation
    is there a workaround for this
    Code (CSharp):
    1.  public string itemName { get; set; }
     
  17. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I know these people well enough and have observed them for years so I know they're not attacking you. Far from, it, in fact they're simply observing that you don't know much about C#. I came to the same conclusion just looking at the code. This is not an attack but a useful observation.

    It allows us to help you at your level of C#. Also we don't care about feelings here. It's about data and facts, which should make you realise there's nothing to fear.
     
    Bunny83 likes this.
  18. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    Your right I'm not fluent in Non-Unity C#. my bad.
    I noticed that Non-Unity C# doesn't translate one to one over to unity.
    Wow, I feel dumb. It's going to take me a while to relearn C#.
    Sorry I didn't realize what everyone was talking about sooner.
     
    Last edited: Oct 16, 2021
  19. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    I have read your deleted comments and I think the best thing would be to just enjoy what you're doing, reminding yourself we are on your side :)
     
    natmaxex likes this.
  20. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    Thank you I will keep that in mind.
     
  21. natmaxex

    natmaxex

    Joined:
    Jul 12, 2012
    Posts:
    68
    This video got taken down, what was it caled and is there a nother one like it?