1

I have a List<GameObject> and I need to remove doubles that have the same position.y and position.x (position.z is irrelevant).

I'm thinking that I need to compare all elements in a list and go through the previous elements of the same list and compare if they have the same positions and then, if not, populate the new List<GameObject>().

I don't really know how to do this as I'm not an experienced programmer.

  • 1
    Define `remove` .. do you only want to remove the entries from the list or do you actually want to remove objects from the scene? What is your exact usecase? Do you need `GameObject` in the end of rather only `Vector2` positions? – derHugo Jun 26 '21 at 16:48

2 Answers2

0

If you wish to just remove the duplicates from an existing list, you don't necessarily have to create a new one. You can iterate over the list and use the RemoveAt method to get rid of the undesired elements.

Example

using System.Collections.Generic;
using UnityEngine;

public class TestScript : MonoBehaviour
{
    public List<GameObject> collection = new List<GameObject>();

    private void Start()
    {
        RemoveDuplicatesFrom(collection);
    }

    private void RemoveDuplicatesFrom(List<GameObject> collection)
    {
        for (int i = 0; i < collection.Count; i++)
        {
            for (int j = i + 1; j < collection.Count; j++)
            {
                if (!Match(collection[i], collection[j]))
                    continue;

                collection.RemoveAt(j);
                j--;
            }
        }
    }

    private bool Match(GameObject object1, GameObject object2)
    {
        return
            object1.transform.position.x == object2.transform.position.x &&
            object1.transform.position.y == object2.transform.position.y;
    }
}
Quickz
  • 1,626
  • 2
  • 11
  • 21
  • Thanks. Questions about RemoveA()t: does the for loop update the List.Count() as it goes? Let's say I have a List.Count() of 4: If I remove [0], does the whole list shift towards [0]? Does [0] become null? If I had a higher number removed, what would happen when iterating to the next for loop iteration? – user3291759 Jun 26 '21 at 11:48
  • @user3291759 `RemoveAt` removes an element entirely at a specific index. So yes, the `Count` value will change and the elements will get shifted. That's why in the code sample `j` variable gets modified upon an element removal. – Quickz Jun 26 '21 at 12:07
  • @user3291759 Feel free to have a look at the Microsoft documentation: https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1.removeat?view=net-5.0#remarks – Quickz Jun 26 '21 at 12:07
  • You should iterate your list in reverse with a for loop when deleting items in that array because it disrupts your current position in the collection. – Dave Jun 26 '21 at 20:16
  • Check this answer https://stackoverflow.com/questions/1582285/how-to-remove-elements-from-a-generic-list-while-iterating-over-it – Dave Jun 26 '21 at 20:17
  • Also comparing positions to match objects like this may not always work due to float imprecision – Dave Jun 26 '21 at 20:22
0

The function below should work just fine

public static List<GameObject> Delete_Doubles(List<GameObject> gameobjects){
                    List<Vector2> occupied_coord = new List<Vector2>();
                    List<GameObject> gameobjects_after = new List<GameObjects>();
                    Vector2 t_vector = new Vector2();
                    Vector3 pos = new Vector3();
                    
                    pos = gameobjects[0].Transform.position;
                    t_vector.x = pos.x;
                    t_vector.y = pos.y;
                    gameobjects_after.Add(gameobjects[0]);
                    occupied_coord.Add(t_vector);
                    
                    for(int i = 1; i < gameobjects.Count; i++)
                    {
                        pos = gameobjects[i].Transform.position;
                        t_vector.x = pos.x;
                        t_vector.y = pos.y;
                        if (!occupied_coord.Contains(t_vector))
                        {
                             gameobjects_after.Add(gameobjects[i]);
                             occupied_coord.Add(t_vector);
                        }
                    }
                    return gameobjects_after;
        }