Dear all,
As the title says: How can I get the most frequent string (that occurred the most) in an array of strings ?
Dear all,
As the title says: How can I get the most frequent string (that occurred the most) in an array of strings ?
There is probably a .NET method for this, but Edward's first thought was to do it manually with a dictionary.
public string MostFrequent(string[] arr)
{
var freq = new Dictionary<string, int>();
Array.ForEach(arr, s => freq[s] = freq.ContainsKey(s) ? freq[s] + 1 : 1);
return (from x in freq orderby x.Value ascending select x).Last().Key;
}
There is probably a more efficient way, and probably a shorter way, but that is what Ed came up with on short notice. ;)
Hi Niemo :icon_wink: this a very old fashion way but at least it works
static string Frequant(int no,string[]s)
{
double[] x = new double[no];
int i, j;
for (i = 0; i < no; i++)
x[i] = 0;
for (j = 0; j < no; j++)
{
for (i = 0; i < no; i++)
{
if (s[j] == s[i] && i != j)
x[j]++;
}
}
double max = 0;
int index = 0;
for (i = 0; i < no; i++)
{
if (x[i] >= max)
{
max = x[i];
index = i;
}
}
return s[index];
}
Here are two methods, one being a LINQ one-liner, the other being similar to Edward's with a dictionary.
static T GetMostFrequentWithLinq<T>(IEnumerable<T> list)
{
return list.GroupBy(val => val).OrderByDescending(grp => grp.Count()).Select(grp => grp.Key).First();
}
static T GetMostFrequent<T>(IEnumerable<T> list)
{
Dictionary<T, int> dictionary = new Dictionary<T, int>();
int maxCount = 0;
T maxItem = default(T);
int currentCount = 0;
foreach (T item in list)
{
if (dictionary.ContainsKey(item))
currentCount = ++dictionary[item];
else
dictionary[item] = currentCount = 1;
if (currentCount > maxCount)
{
maxCount = currentCount;
maxItem = item;
}
}
return maxItem;
}
The second should be more efficient, as it only needs a single pass over the list, and lookups in dictionaries are fast. But for small lists, it might not be evident and really doesn't matter.
You could do it without the dictionary by sorting the array then finding the longest sequence. Of course, this requires altering the element order and is less generic (can't sort IEnumerable). Here's apegram's code modified to do that:
T GetMostFrequent<T>(T[] list) where T : class
{
Array.Sort(list);
int currentCount = 0;
int maxCount = 0;
T prevItem = null;
T maxItem = null;
foreach (T item in list)
{
if (++currentCount >= maxCount)
{
maxCount = currentCount;
maxItem = item;
}
if (item != prevItem)
currentCount = 1;
else
prevItem = item;
}
return maxItem;
}
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.