#156 – Using break and continue in foreach Loops

When iterating through array elements using the foreach statement, you can use the break statement to break out of the loop–when break is encountered, control is transferred to the code immediately following the loop and no more array elements will be processed.

            foreach (Person p in folks)
                Console.WriteLine("{0} {1}", p.FirstName, p.LastName);

                // If we find Elvis, stop the presses
                if (p.FirstName == "Elvis")

The continue statement, when encountered in a foreach loop, causes control to transfer back to the top of the loop and move on to the next element.

            foreach (Person p in folks)
                // Don't print out info for any Adolfs; move to the next person
                if (p.FirstName == "Adolf")

                Console.WriteLine("{0} {1}", p.FirstName, p.LastName);

#155 – Iterating Through an Array Using the foreach Statement

You can write a loop–a block of code that is executed more than once–that executes once for each element in an array, using the C# foreach statement.

The foreach statement declares a variable local to the loop of the same type of the elements in the array.  This variable takes on the value of each element in the array.

            Person[] folks = new Person[4];
        	folks[0] = new Person("Bronte", "Emily");
	        folks[1] = new Person("Bronte", "Charlotte");
	        folks[2] = new Person("Tennyson", "Alfred");
	        folks[3] = new Person("Mailer", "Norman");

            string sLastNameList = "";

            // For each Person in array, dump out name and concatenate last name
            foreach (Person p in folks)
                Console.WriteLine("{0} {1}", p.FirstName, p.LastName);
                sLastNameList += p.LastName;

#154 – Using an Invalid Array Index Causes an Exception to Be Thrown

If you try to reference an array element using an index that is outside the declared range of the array, an IndexOutOfRangeException exception will be thrown.

            int[] scores = { 88, 99, 79, 88};
            Console.WriteLine("5th element? - {0}", scores[4]);    // IndexOutOfRangeException

#153 – Returning a Subset of Array Elements Matching a Particular Criteria

Because System.Array implements the IEnumerable interface and because LINQ extends IEnumerable, you can use the IEnumerable.Where method on arrays to find a subset of elements that match a particular criteria.

The Where method accepts a delegate to a function that takes a single element of the same type as the array and returns a boolean value, indicating whether a match is found.  Where returns an IEnumerable collection, which can be iterated on to get the elements in the subset.

Here’s an example, finding the set of passing scores in a set of scores.

            int[] scores = { 89, 98, 72, 100, 68 };

            // Count number of passing grades
            int numPassed = scores.Where((Func<int,bool>)IsPassingGrade).Count();

Here’s the implementation of IsPassingGrade.

        static bool IsPassingGrade(int score)
            return (score >= 75);

You can avoid defining a separate function by using a lamba expression.

            int numPassed = scores.Where(s => s >= 75).Count();

Similar to Array.FindAll.

#152 – Remove Duplicate Array Entries Using Distinct() Method

You can use the IEnumerable.Distinct method on an array to get all of the elements of the array, with the duplicates removed.

This method returns a result of the type IEnumerable<T>, where T is the type of the element in the array.  You can iterate through this new list using the foreach statement, or count the number of elements using the Count method.

            int[] scores = { 88, 99, 79, 88, 78, 100, 79 };

            // # of unique scores
            Console.WriteLine("# unique = {0}", scores.Distinct().Count());   // 5

            // List only the unique scores
            foreach (int next in scores.Distinct())
                Console.WriteLine("Score : {0}", next);

#151 – Determining Whether an Array Contains a Specific Element

You can use the Array.Find method to find a particular element in an array.  If, however, you only care whether a particular element is present in an array, you can use the IEnumerable.Contains method.  The Contains method returns true if the element was found in the array, false if not.

            int[] scores = { 89, 98, 72, 100, 83 };

            bool someoneAcedIt = scores.Contains(100);   // true

Contains also works on arrays holding objects belonging to a custom type.

            Person[] folks = new Person[3];
            folks[0] = new Person("Bronte", "Emily", 29);
            folks[1] = new Person("Bronte", "Charlotte", 31);
            folks[2] = new Person("Tennyson", "Alfred", 24);

            bool foundAlfred = folks.Contains(new Person("Tennyson", "Alfred", 24));

This will only work as expected if the underlying type has implemented the equality operator in a way that properly compares two objects to determine if they are equal.  If the equality operator has not been defined, only the references to the objects will be compared, rather than the contents of the objects.

#150 – Other Aggregate Functions You Can Apply to Numeric Arrays

Post #147 mentioned using IEnumerable.Average to get the average of an array of numeric values.  The System.Linq namespace includes several other extension methods for IEnumerable that can be used to aggregate values:

  • Max – Get the maximum value
  • Min – Get the minimum value
  • Sum – Get the sum of all values
            int[] scores = { 89, 98, 72, 100, 83 };
            int sum = scores.Sum();        // 442
            int min = scores.Min();        // 72
            int max = scores.Max();        // 100
            double avg = scores.Average();       // 88.4

#149 – Using IEnumerable.Aggregate to Perform a Calculation Based on All Elements in an Array

IEnumerable.Average can be used to perform an average across all elements in an array.  Instead of doing an average, we can perform our own custom calculation across all elements, using the IEnumerable.Aggregate function.

Aggregate works by specifying a function that will get called once for each element in the array (except for the first element).  The function’s arguments are:

  • On 1st pass: 1st and 2nd elements are passed to the function
  • On 2nd thru (n-1)th pass: result of previous pass is passed as 1st parameter, next element as 2nd parameter

The return value is used to store the result of your aggregate function and is passed back to the function on the next pass.

Here’s an example:

        public static Person CombinePeople(Person prevResult, Person next)
            return new Person(prevResult.FirstName + next.FirstName,
                prevResult.LastName + next.LastName,
                prevResult.Age + next.Age);

        // Example of calling Aggregate
        Person pCombined = folks.Aggregate((Func<Person,Person,Person>)CombinePeople);

#148 – Getting the Average of an Array of Custom Objects

If you want to calculate the average (mean) of a collection of objects stored in an array, you can use the IEnumerable.Average method.

The Average method allows passing in an indication of the function that should be used to calculate the numeric value from each object, which will be used in generating the average.  This function takes an object whose type matches the type of the array as an input parameter and returns a numeric value, used in generating the average.  It will be called once for each element of the array.

You could define a static function and pass a delegate to that function.

        static int AgeOf(Person p)
            return p.Age;

        // Example of calling Average on Person[] array
        double avgAge = folks.Average((Func<Person,int>)AgeOf);

Alternatively, you could use a lambda expression, avoiding the need to define a separate function.

            double avgAge = folks.Average(person => person.Age);

#147 – Getting the Average of an Array of Numbers

If you have an array containing a collection of numeric values, you can get the average (mean) using the Average method.

            int[] scores = { 89, 98, 72, 100, 83 };

            double avg = scores.Average();      // 88.4

The Average method is an extension method, applied to Array by virtue of its implementation of the IEnumerable interface.  It’s part of the System.Linq namespace, so you’ll need a using statement for this namespace.  Average is available in .NET 4 and 3.5.

Average will work for arrays containing any numeric type.