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