简体   繁体   中英

ASP.NET Core MVC Calculate percentage of ENUM

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();
       }
   }
}

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
            });

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

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);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM