Sunday 20 January 2013

Remove an Item from a Collection

Seem quite a few posts and questions on removing an item from a collection, most are fairly bad if not very bad coding examples.

Common Issue

If you try and alter a collection from within a foreach loop then it will throw and exception ( and quite rightly so).

        

          var people = new List()
                {
                    new Person() {Id = 0, Name = "Bob"},
                    new Person() {Id = 1, Name = "Rob"},
                    new Person() {Id = 2, Name = "Ann"},
                };

            //THIS WILL CRASH AND IS CRAPPY CODE REGARDLESS
            foreach (var person in people)
            {
                if (person.Id == 1)
                    people.Remove(person);
            }




What NOT TO DO

Although this will work it is not very good code. Can you spot the issues ?? (answers below)

        

            var people = new List()
                {
                    new Person() {Id = 0, Name = "Bob"},
                    new Person() {Id = 1, Name = "Rob"},
                    new Person() {Id = 2, Name = "Ann"},
                };


            var finder = new List();

            foreach (var person in people)
            {
                if (person.Id == 2)
                    finder.Add(person);
            }

            foreach (var person in finder)
            {
                people.Remove(person);
            }





  • You iterate through the entire collection even of the search item is the first item there.
  • It will be slow for large collections
  • Other developers will laugh at you (or shake their head and mutter in despair) 


Easy Method

A must more efficient method is pull the item you want to remove via a Find on the collection and

        

            var people = new List()
                {
                    new Person() {Id = 0, Name = "Bob"},
                    new Person() {Id = 1, Name = "Rob"},
                    new Person() {Id = 2, Name = "Ann"},
                };

           
            //USE THIS 
            var getperson = people.Find(x => x.Id == 1);

            people.Remove(getperson)


In the above code you might think that it will throw an exception if there is no search results, but List.Remove(null) does not throw an exception.

Combine Search and Remove on Single Command Line

You can also combine the search

 
            var people = new List()
                {
                    new Person() {Id = 0, Name = "Bob"},
                    new Person() {Id = 1, Name = "Rob"},
                    new Person() {Id = 2, Name = "Ann"},
                };


            people.Remove(people.Find(x =>; x.Id == 0));



Remove Multiple with a Search  with RemoveAll


 
            var people = new List()
                {
                    new Person() {Id = 0, Name = "Bob"},
                    new Person() {Id = 1, Name = "Rob"},
                    new Person() {Id = 2, Name = "Ann"},
                };


            people.RemoveAll(x =>; x.Id > 0));



Remove Multiple with another Collection


 
            var people = new List()
                {
                    new Person() {Id = 0, Name = "Bob"},
                    new Person() {Id = 1, Name = "Rob"},
                    new Person() {Id = 2, Name = "Ann"},
                };
            // Collection of Ints
            var findpeople = new List() {1, 2};
            
            // Remove people with Ids from the collection
            people.RemoveAll(x=>;  findpeople.Contains(x.Id));

     



Remove with FindIndex

          

            var people = new List()
                {
                    new Person() {Id = 0, Name = "Bob"},
                    new Person() {Id = 1, Name = "Rob"},
                    new Person() {Id = 2, Name = "Ann"},
                };

            people.RemoveAt(people.FindIndex(x=> x.Id == 2));




Well I hope this helps.



No comments:

Post a Comment

Comments are welcome, but are moderated and may take a wee while before shown.