Something like this should work (you need to get the ValueTuple NuGet package for that tuple call signature to work):
public static IEnumerable<int> ListOfInts = new List<int> { 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 4, 5 };
public static (int? mostFrequent, int numOccurances) FindMostFrequent(IEnumerable<int> ints) {
int maxNumOccurances = int.MinValue;
int? mostFrequent = null;
//key is number (that occurs), value is number of occurances
var counters = new Dictionary<int, int>();
foreach (var num in ints) {
if (counters.TryGetValue(num, out var occurances)) {
counters[num] = ++occurances;
} else {
counters[num] = 1;
}
if (occurances > maxNumOccurances) {
mostFrequent = num;
maxNumOccurances = occurances;
}
}
return (mostFrequent, maxNumOccurances);
}
It goes through the integer collection once. It builds a Dictionary<int, int>
as it walks through the list, doing N lookups and N writes (either inserts or replacements).
If the list is empty, the mostFrequent
part of the return will be null
. If there the maximum occurs more than once, you'll get the first one that's found. If you want the last, change the >
to >=
in:
if (occurances > maxNumOccurances)
and, if you want all possible results, do something like this before the return:
var maxes = from pair in counters where pair.Value == maxNumOccurances select pair;