How do I display the common number? but if other numbers are just as common, I want to be able to display multiple.
So I have an array with a max length of 24, I can generate random number between 1-100 and sort them.
Looks something like this.. 2 8 9 10 13 19 20 38 43 47 51 55 55 59 66 67 73 84 87 87 93 95 98 100
So the most common numbers are 55 and 87, as 55 and 87 show up twice.
Here's my code..
private void buttonMode_Click(object sender, EventArgs e)
{
int mode = 0;
int max = 0;
var counts = new Dictionary<int, int>();
foreach (int value in dataArray)
{
if (counts.ContainsKey(value))
{
counts[value] ;
}
else
{
counts.Add(value, 1);
}
}
foreach(KeyValuePair<int,int> count in counts)
{
if (count.Value > max)
{
mode = count.Key;
max = count.Value;
}
}
textBoxOut1.Text = $"Mode is: {mode}";
}
This only displays the lowest common value, which using the example above would be 55 only. I've searched and by using .Max this can be done, but how?
CodePudding user response:
You can use GroupBy
, one for the int
-value and the other for the group-sizes:
List<List<int>> maxGroups = dataArray
.GroupBy(i => i) // group by int-value
.GroupBy(g => g.Count(), g => g.ToList()) // group groups by size
.OrderByDescending(g => g.Key) // get biggest group
.First()
.ToList();
This gives you a list with two sub-lists, each contain 2 integers, one 55 and the other 87.
If you want to use your counts-dictionary, you could use this:
int maxCount = counts.Values.Max();
List<(int value, int count)> maxValueCounts = counts
.Where(kv => kv.Value == maxCount)
.Select(kv => (kv.Key, kv.Value))
.ToList();
Here you get a list with the max-count values in a named tuple.
CodePudding user response:
You could use 'textBoxOut1.Text = mode ", "' in you 2nd foreach.
Hint: To make the code easier to debug and read, separate it into multiple functions : 'List CountOccurences(List list)' and 'List FindTopMostCommon(List list)' (Or what ever you like for naming).
Or short it all down to Linq as Time suggested
CodePudding user response:
You could also replace the foreach
on the counts
dictionary with the following code:
var modes = counts.Where(count => count.Value == counts.Values.Max());
var output = string.Join(", ", modes.Select(c => c.Key.ToString()));
textBoxOut1.Text = $"Mode is: {output}";
CodePudding user response:
In my solution you don't need any loops.
var dict = dataArray.GroupBy(x => x)
.ToDictionary(x => x.Key, x => x.Count());
var max = dict.Values.Max();
var modes = dict.Where(x => x.Value == max)
.Select(x => x.Key);