c# - 在 C# 中使用 Dictionary<T, Func<List, bool>> 查找列表中最常见的事件

标签 c# dictionary lambda delegates func

假设我的 C# 代码定义如下,我想向我的控制台返回一个显示列表或汽车中最常见燃料类型的输出。

// set delegates defining rules as a function that takes list of cars and returns an int
Func<List<Car>, int> CountElectric = (cars) => cars
    .GroupBy(c => c.IsElectric == true).Count(); // count electric cars

Func<List<Car>, int> CountGassoline = (cars) => cars
    .GroupBy(c => c.FuelType == FuelTypes.Gassoline).Count(); // count cars using gassoline

Func<List<Car>, int> CountDiesel = (cars) => cars
    .GroupBy(c => c.FuelType == FuelTypes.Diesel).Count(); // Count cars using diesel

// Add rules to dictionary of (Key=CarType, Value=Func<List<Car>, bool>
CarsRules = new Dictionary<CarType, Func<List<Car>, int>>()
{
    {FueldType.Electric, CountElectric},
    {FueldType.Diesel,CountDiesel},
    {FueldType.Gassoline, CountGassoline}
};

// Create List of Cars and add some cars
List<Car> cars = new List<Car>();

cars.Add(new Car() 
{Id = Guid, Name = "Tesla", IsElectric = true, FuelType = FuelTypes.Electric};

cars.Add(new Car() 
{Id = Guid, Name = "VW", IsElectric = false, FuelType = FuelTypes.Gassoline};

cars.Add(new Car() 
{Id = Guid, Name = "Toyota", IsElectric = false, FuelType = FuelTypes.Gassoline};

cars.Add(new Car() 
{Id = Guid, Name = "Volvo", IsElectric = false, FuelType = FuelTypes.Diesel};

在上面的汽车列表中,汽油是最常见的。我如何找到它? I.E 我只想在控制台上显示“Gassoline”

如果我在上面的列表中有平局,例如 2 辆使用汽油的汽车和 2 辆使用柴油的汽车,我如何找到并归还这两辆汽车? I.E 我想在控制台上同时显示“汽油”和“柴油”

我很难理解这种结构,我想像下面这样用老式的方式来做,但我很清楚应该有更优雅的方式来使用 Func 委托(delegate)

public List<string> GetMostUsedFuelTypes(List<Car> cars)
{
    List<string> winners = new List<string>();

    int CountElectric = 0;
    int CountGassoline = 0;
    int CountDiesel = 0;

    foreach(var car in cars)
    {
        // Count and return fuel type that occurs most, if a tye, return the highest counts
    }

    return winners;
}

最佳答案

你的结构Dictionary<CarType, Func<List<Car>, int>>是做这种事的错误类型。您可以组合两个 int如果您尝试将具有重叠子集的类型组合在一起,则可以获得准确的计数值。

这是我会做的:

var CarsRules = new Dictionary<FuelTypes, Func<List<Car>, IEnumerable<Car>>>()
{
    { FuelTypes.Electric, cs => cs.Where(c => c.IsElectric) },
    { FuelTypes.Diesel, cs => cs.Where(c => c.FuelType == FuelTypes.Diesel) },
    { FuelTypes.Gassoline, cs => cs.Where(c => c.FuelType == FuelTypes.Gassoline) },
}

List<Car> cars = new List<Car>()
{
    new Car(Guid.NewGuid(), "Tesla", true, FuelTypes.Electric),
    new Car(Guid.NewGuid(), "VW", false, FuelTypes.Gassoline),
    new Car(Guid.NewGuid(), "Toyota", false, FuelTypes.Gassoline),
    new Car(Guid.NewGuid(), "Volvo", false, FuelTypes.Diesel),
};

Console.WriteLine($"Electric: {CarsRules[FuelTypes.Electric](cars).Count()}");
Console.WriteLine($"Gassoline: {CarsRules[FuelTypes.Gassoline](cars).Count()}");
Console.WriteLine($"Diesel: {CarsRules[FuelTypes.Diesel](cars).Count()}");
Console.WriteLine($"Gassoline & Diesel: {CarsRules[FuelTypes.Gassoline](cars).Union(CarsRules[FuelTypes.Diesel](cars)).Count()}");

这需要定义这些类型:

public enum FuelTypes
{
    Electric, Gassoline, Diesel
}

public sealed class Car : IEquatable<Car>
{
    private readonly Guid _Id;
    private readonly string _Name;
    private readonly bool _IsElectric;
    private readonly FuelTypes _FuelType;

    public Guid Id { get { return _Id; } }
    public string Name { get { return _Name; } }
    public bool IsElectric { get { return _IsElectric; } }
    public FuelTypes FuelType { get { return _FuelType; } }

    public Car(Guid Id, string Name, bool IsElectric, FuelTypes FuelType)
    {
        _Id = Id;
        _Name = Name;
        _IsElectric = IsElectric;
        _FuelType = FuelType;
    }

    public override bool Equals(object obj)
    {
        if (obj is Car)
            return Equals((Car)obj);
        return false;
    }

    public bool Equals(Car obj)
    {
        if (obj == null) return false;
        if (!EqualityComparer<Guid>.Default.Equals(_Id, obj._Id)) return false;
        if (!EqualityComparer<string>.Default.Equals(_Name, obj._Name)) return false;
        if (!EqualityComparer<bool>.Default.Equals(_IsElectric, obj._IsElectric)) return false;
        if (!EqualityComparer<FuelTypes>.Default.Equals(_FuelType, obj._FuelType)) return false;
        return true;
    }

    public override int GetHashCode()
    {
        int hash = 0;
        hash ^= EqualityComparer<Guid>.Default.GetHashCode(_Id);
        hash ^= EqualityComparer<string>.Default.GetHashCode(_Name);
        hash ^= EqualityComparer<bool>.Default.GetHashCode(_IsElectric);
        hash ^= EqualityComparer<FuelTypes>.Default.GetHashCode(_FuelType);
        return hash;
    }

    public override string ToString()
    {
        return String.Format("{{ Id = {0}, Name = {1}, IsElectric = {2}, FuelType = {3} }}", _Id, _Name, _IsElectric, _FuelType);
    }

    public static bool operator ==(Car left, Car right)
    {
        if (object.ReferenceEquals(left, null))
        {
            return object.ReferenceEquals(right, null);
        }

        return left.Equals(right);
    }

    public static bool operator !=(Car left, Car right)
    {
        return !(left == right);
    }
}

关于c# - 在 C# 中使用 Dictionary<T, Func<List, bool>> 查找列表中最常见的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50732657/

相关文章:

java - 如何从java中给定的 map 值查找最新日期

c# - .NET 中的 "managed"与 "unmanaged"资源是什么意思?

ios - 我怎样才能用单个标记多次敲击

python:在字典中创建一个列表

c++ - 当使用私有(private)成员变量时,传递 lambda 是否违反封装?

java - 如何在 lambda 中进行 If-or 运算

c# - 使用 .NET 和 Xamarin 的服务器客户端应用程序

c# - .Net Core 2.0 中的 Windows 和匿名身份验证

c# - 奇怪的网络设备

c++ - 使用双迭代器引用 map 中的列表