I'm scrubbing 5 files for a specific value. I dont anticipate any different values, BUT since this is for my own educational purposes, I would like the application to count, compare and print the most popular value.
for example:
ArrayList arrName = new ArrayList();
arrName.Add("BOB")
arrName.Add("JOHN")
arrName.Add("TOM")
arrName.Add("TOM")
arrName.Add("TOM")
The result I would like is going to be TOM but being a novice, I really dont know how to move forward.
Any thoughts, suggestions or examples are greatly appreciated. Thank you.
You can easily do this with LINQ if you can use it, with a query similar to
names.Distinct().OrderByDescending(s => names.Count(u => u == s))).FirstOrDefault();
It will return the value with the highest count, or default(Type)
. In cases of equivalent counts, it will return the first one with he highest count. You can put that method in your extensions with generics for general usage.
class Program
{
static void Main(string[] args)
{
IEnumerable<String> names = new String[] { "BOB",
"JOHN",
"TOM",
"TOM",
"TOM" };
var res = names.Top(); //returns "TOM"
}
}
public static class Extensions
{
public static T Top<T>(this IEnumerable<T> values)
{
return values.Distinct().OrderByDescending(s => values.Count(u => u.Equals(s))).FirstOrDefault();
}
}
If you need all values that have the highest count, like if your list was "BOB", "JOHN", "JOHN", "TOM", "TOM"
I guess you could use this version instead in order to return both JOHN and TOM:
public static IEnumerable<T> Top<T>(this IEnumerable<T> values)
{
List<T> ret = new List<T>();
int max = -1;
foreach (var val in values.Distinct())
{
int count = values.Count(t => t.Equals(val));
if (count >= max)
{
if (count > max)
{
ret.Clear();
max = count;
}
ret.Add(val); //stacks equivalent count, if applicable
}
}
return ret;
}
You didn't specify the version of .Net / C# you are using, so I'll treat this for each version of C#: v1, v2 and v3.
C# V1:
class CountValueComparer : IComparer
{
public int Compare(object x, object y)
{
DictionaryEntry left = (DictionaryEntry)x;
DictionaryEntry right = (DictionaryEntry)y;
return ((int)left.Value).CompareTo((int)right.Value);
}
}
Hashtable counts = new Hashtable();
foreach(String value in arrName)
{
if (counts.ContainsKey(value))
{
int valueCount = (int)counts[value];
++valueCount;
counts[value] = valueCount;
}
else
{
counts[value] = 1;
}
}
DictionaryEntry[] sorted = new DictionaryEntry[counts.Count];
counts.CopyTo(sorted, 0);
Array.Sort(sorted, new CountValueComparer());
foreach (DictionaryEntry entry in sorted)
{
Console.Writeline("Name: {0}; Count: {1}", entry.Key, entry.Value);
}
C# V2:
class CountValueComparer : IComparer<KeyValuePair<String, int>>
{
public int Compare(int x, int y)
{
return x.Value.CompareTo(y.Value);
}
}
// if v2, use the List<T> class!
List<String> arrName = new List<String>();
arrName.Add("TOM");
// etc...
Dictionary<String, int> counts = new Dictionary<String, int>();
foreach(String value in arrName)
{
int count;
if (counts.TryGetValue(value, out count))
{
counts[value] = ++count;
}
else
{
counts[value] = 1;
}
}
KeyValuePair<String, int>[] sorted = new KeyValuePair<String, int>[counts.Count];
counts.CopyTo(sorted, 0);
Array.Sort(sorted, new CountValueComparer());
C# V3:
// if v3, use the List<T> class!
var arrName = new List<String>();
arrName.Add("TOM");
// etc...
var counts = (from n in arrName
group n by n into g
select new { Name = g.Key, Count = g.Count() })
.OrderByDescending(x => x.Count);
var top = counts.FirstOrDefault();
Console.WriteLine("Name: {0}; Count: {1}", top.Name, top.Count);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With