0
\$\begingroup\$

What is the best way, in terms of performance, to remove a list (a group of elements such as integers or strings) from another list, other than using for or foreach loops?

For example, is there a function that takes a list as a parameter and removes every element in it?, similar to List.AddRange(), which takes a list as a parameter and adds every element from it.

public class ListsManager : MonoBehaviour
{
    [SerializeField] private List<int> _list = new List<int>() { 1, 2, 3, 4, 5, 7, 8, 9, 10 };
    [SerializeField] private List<int> _listToRemove = new List<int>() { 1, 3, 5, 7, 9 };

    void Start()
    {
        for (int i = 0; i < _listToRemove.Count; i++)
        {
            _list.Remove(_listToRemove[i]);
        }
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ Does this answer your question? Remove items from one list in another \$\endgroup\$
    – DMGregory
    Commented yesterday
  • \$\begingroup\$ I think no because the method in this answer depends on creating a new list which will consume more memory \$\endgroup\$
    – Ahmed Dyaa
    Commented yesterday
  • 1
    \$\begingroup\$ Note that there is more than one answer at that link, including several that do not allocate a new list. You have a menu of options to choose from here. Is there a specific criterion you have that no answer posted at this link satisfies? \$\endgroup\$
    – DMGregory
    Commented yesterday
  • 1
    \$\begingroup\$ Is this a theoretical problem or do you have a performance issue based related to list filtering? Depending on your context it might be the case that lists are the wrong data structure for the underlying task. What are you doing with the lists? How large are they? How often do they change & by how much? Describing your actual problem is more likely to yield an actual solution. \$\endgroup\$
    – Pikalek
    Commented yesterday

1 Answer 1

2
\$\begingroup\$

To remove elements from one list using another list in C#, you can use the RemoveAll method with a lambda. It's clean and avoids manual loops. Here's an example:

using System.Collections.Generic;
using UnityEngine;

public class ListsManager : MonoBehaviour {

    [SerializeField]
    private List<int> _list = new List<int>() { 1, 2, 3, 4, 5, 7, 8, 9, 10 }; 

    [SerializeField]  
    private List<int> _listToRemove = new List<int>() { 3, 4, 7 }; 

    private void Start() { 

        _list.RemoveAll(item => _listToRemove.Contains(item)); 

        Debug.Log(string.Join(", ", _list));
        // Outputs: 1, 2, 5, 8, 9, 10 
    }
} 
\$\endgroup\$
2
  • \$\begingroup\$ Note that this solution is one of the ones already offered via the StackOverflow link shared in the comments. \$\endgroup\$
    – DMGregory
    Commented 13 hours ago
  • \$\begingroup\$ While this avoids manual loops, behind the scene this is still a nested loop process (as described here. It is cleaner & probably easier to maintain. From a performance standpoint though, it simply pushes the looping behind the method call. \$\endgroup\$
    – Pikalek
    Commented 12 hours ago

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .