Reputation: 137
How can I calculate the percentage of occurences from a ENUM ? I have a list of bookings and I have 2 different types of sockets in my ENUM. For example if booking_1 has type_1, booking_2 has type_1 and then booking_3 has type_2 I should get in my View table that type_1 is used 66.6% and type_2 33.3%
Here is my ENUM:
namespace WebApplication.Models
{
public enum ConnectorType
{
[Display(Name = "Type 2-Plug")]
Type2Plug,
[Display(Name = "CCS Combo 2-Plug")]
CCSCombo2Plug
}
}
Here is the ViewModel:
namespace WebApplication.ViewModels
{
public class ConnectorTypeEvaluationViewModel
{
[Display(Name = "Anschlusstyp")]
public ConnectorType connectorType { get; set; }
[Display(Name = "Prozentsatz")]
public double connectorPercentage { get; set; }
}
}
And my problem is with the Controller. I somehow need to use a loop to calculate the percentage of each occurence of my ENUM types in my bookingsList but I have no idea how:
namespace WebApplication.Controllers
{
public class ConnectorTypeEvaluationController : Controller
{
private IMemoryCache _cache;
public ConnectorTypeEvaluationController(IMemoryCache cache)
{
_cache = cache;
}
public IActionResult Index()
{
List<Booking> bookingsList;
_cache.TryGetValue("key", out bookingsList);
double total = bookingsList.Count;
connectorType = ??;
connectorPercentage = ??;
return View();
}
}
}
Upvotes: 0
Views: 842
Reputation: 3641
Percentage calculation is (i / n) * 100
where n
is the total number of observations and i
is example the number of Type2Plug.
Could probably be optimize somehow, maybe by using GroupBy
.
public IActionResult Index()
{
List<Booking> bookingsList;
_cache.TryGetValue("key", out bookingsList);
double type2PlugCount = bookingsList.Count(x => x.connectorType == ConnectorType.Type2Plug);
double cCSCombo2PlugCount = bookingsList.Count(x => x.connectorType == ConnectorType.CCSCombo2Plug);
double total = bookingsList.Count;
var type2PlugPercentage = (type2PlugCount / total) * 100;
var cCSCombo2PlugPercentage = (cCSCombo2PlugCount / total) * 100;
return View();
}
EDIT
I create a generic way to calculate percentage based on a property
public static Dictionary<TProperty, double> Percentage<T, TProperty>(this IEnumerable<T> source, Expression<Func<T,TProperty>> selector)
{
var dict = new Dictionary<TProperty, double>();
Func<T,TProperty> func = selector.Compile();
var list = source.ToList();
var groups = list.GroupBy(func).ToList();
double total = list.Count;
foreach(var group in groups)
{
double groupCount = group.Count();
var percentage = (groupCount / total) * 100;
dict.Add(group.Key, percentage);
}
return dict;
}
Usage
var dict = list.Percentage(x => x.SomeProperty);
https://dotnetfiddle.net/Hqy9GV
Upvotes: 1
Reputation: 137
Thanks a lot for the help! I managed to make a foreach loop to add every type so if I need more types i don't have to add all of them manually. Here is the code:
namespace WebApplication.Controllers
{
public class ConnectorTypeEvaluationController : Controller
{
private IMemoryCache _cache;
public ConnectorTypeEvaluationController(IMemoryCache cache)
{
_cache = cache;
}
public IActionResult Index()
{
List<Booking> bookingsList;
_cache.TryGetValue("key", out bookingsList);
List<ConnectorTypeEvaluationViewModel> connectorsList = new List<ConnectorTypeEvaluationViewModel>();
var connectors = Enum.GetValues(typeof(ConnectorType)).Cast<ConnectorType>();
foreach (var item in connectors)
{
connectorsList.Add(new ConnectorTypeEvaluationViewModel
{
connectorType = item,
connectorPercentage = (bookingsList.Count(s => s.connectorType == item) / Convert.ToDouble(bookingsList.Count())) * 100
});
}
return View(connectorsList);
}
}
}
Upvotes: 0
Reputation: 1304
As I understand you want to calculate percentage per connectorType for all bookings. Create a list with these two connector and calculate percentage as below :
List<ConnectorTypeEvaluationViewModel> connectorTypeEvaluationViewModel = new List<ConnectorTypeEvaluationViewModel>();
connectorTypeEvaluationViewModel.Add(new ConnectorTypeEvaluationViewModel
{
connectorType = ConnectorType.Type2Plug,
connectorPercentage = (bookingsList.Count(s => s.connectorType==ConnectorType.Type2Plug)/Convert.ToDouble(bookingsList.Count()))*100
});
connectorTypeEvaluationViewModel.Add(new ConnectorTypeEvaluationViewModel
{
connectorType = ConnectorType.CCSCombo2Plug,
connectorPercentage = (bookingsList.Count(s => s.connectorType== ConnectorType.CCSCombo2Plug) / Convert.ToDouble(bookingsList.Count())) * 100
});
Upvotes: 2