C#: Get the most common elements (Mode(s)) from a List

I’m writing this post after reading Nick Olsen’s post on the same subject but his piece was about finding the mode from a uni-modal collection (a set with only one mode).

For example in the set { 1 , 2, 3, 4, 4, 4, 5, 6, 7}. There is no disputing that the mode would be 4.

However in the set { 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 7}. This is a bi-modal or multi-modal set, where the mode is 3 and 4.

In some cases just saying that 3 is the mode would be enough, but how can we get both values if we need them?

Well pretty simple once we know the mode and how many times the element occurred to make it the mode just go back over our dictionary, find all elements that occurred the same number of times and add them to a list which we can then return to the caller.

		public static List<T> Mode<T>(this List<T> list)
		{
			var modeList = new List();

			// Test for a null reference and an empty list
			if (list != null && list.Count() > 0)
			{
				// Store the number of occurrences for each element
				var counts = new Dictionary<T, int>();

				// Add one to the count for the occurrence of an element
				foreach (var element in list)
				{
					if (counts.ContainsKey(element))
						counts[element]++;
					else
						counts.Add(element, 1);
				}

				// Loop through the counts of each element and find the
				// element that occurred most often
				var max = 0;
				foreach (var count in counts)
				{
					if (count.Value <= max) continue;
					max = count.Value;
				}

				foreach (var count in counts)
				{
					if (count.Value == max)
						modeList.Add(count.Key);
				}
			}

			return modeList;
		}

On a side note I also needed to find out how many times the mode(s) had occurred in the set.

		public static List<T> Mode<T>(this IEnumerable<T> list, out int occurrencesPerMode)
		{
			var modeList = new List<T>();
			occurrencesPerMode = 0;

			// Test for a null reference and an empty list
			if (list != null && list.Count() > 0)
			{
				// Store the number of occurences for each element
				var counts = new Dictionary<T, int>();

				// Add one to the count for the occurence of a character
				foreach (var element in list)
				{
					if (counts.ContainsKey(element))
						counts[element]++;
					else
						counts.Add(element, 1);
				}

				// Loop through the counts of each element and find the
				// element that occurred most often
				var max = 0;
				foreach (var count in counts)
				{
					if (count.Value <= max) continue;
					max = count.Value;
				}
				occurrencesPerMode = max;

				foreach (var count in counts)
				{
					if (count.Value == max)
						modeList.Add(count.Key);
				}
			}

			return modeList;
		}

Usage

 var list = new List<byte> { 1, 2, 3, 3, 3, 4, 4, 4, 5, 6, 7};
 int occurrences;
 var modes = Set.Mode(out occurrences);
 modes.ForEach(mode => Console.WriteLine("Mode: {0}", mode));
 Console.WriteLine("Occurred {1} times.", occurrences);
 //Output
 //------
 //Mode: 3
 //Mode: 4
 //Occurred 3 times.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s