在 C# 中查找 3 个复杂字典之间的差异

Finding differences between 3 complicated dictionaries in C#

我无法同时使用 3 部词典来查找差异,例如缺失条目和 属性 值。 字典键和值是这些对象:

public class Car
{
    public string CarBrand{ get; set; }
    public string RentingCompany{ get; set; }
    public string CompanyPhone{ get; set; }
    public ComplexObj MyObj { get; set; } //This is a deserialized XML
}

public class Drivers
{
    public string DriverID{ get; set; } // Unique

    public string Name{ get; set; }

    public string LastName{ get; set; }
}
    public Dictionary<Drivers, List<Car>> List1 = new Dictionary<Drivers, List<Car>>();
    public Dictionary<Drivers, List<Car>> List2 = new Dictionary<Drivers, List<Car>>();
    public Dictionary<Drivers, List<Car>> List3 = new Dictionary<Drivers, List<Car>>();

我需要在 List1.Values 中搜索所有不在 list2 或 List3 中的 CarBrands,并将整个 KeyValue 对 Driver 和 Value 保存到新字典中。 我很乐意接受关于什么是解决此问题的最佳方法的任何指导。

谢谢

var brands2 = List2.Values.SelectMany(v => v.Select(c => c.CarBrand));
var brands3 = List3.Values.SelectMany(v => v.Select(c => c.CarBrand));
var allBrands = brands2.Concat(brands3);

var keyValuePairsToSave = List1
    .Where(pair => !pair.Value.Any(car => allBrands.Any(brand => brand == car.CarBrand)))
    // or
    //.Where(pair => !allBrands.Any(brand => pair.Value.Any(c => c.CarBrand == brand)))
    .ToArray();
    //or
    //.ToDictionary(pair => pair.Key, pair => pair.Value);

这种方法比将列表 1 中的每个汽车品牌与列表 2 和列表 3 中的每个汽车品牌进行比较要快得多。另一个答案中显示的方法具有很高的计算复杂度,它对于大量数据的扩展性很差。

我还没有真正测试过,但我认为它是正确的。

// only the distinct car brands throughout list2 and list3 remain in this hash set
HashSet<string> carBrandsInlist2and3 = new(
    List2.Values
    .Concat(List3.Values)
    .SelectMany(cars => cars.Select(car => car.CarBrand)));

// using a hashset for IsSubsetOf below is going to be much quicker than
// using a 'simple' IEnumerable because set operations have optimizations in place in case
// both sets are of the same type and have the same IEqualityComparer
HashSet<string> tempHashset = new();

Dictionary<Drivers, List<Car>> newDictionary = new(
    List1
    .Where(keyValuePair =>
    {
        // fill the temporary hashset with car brands of this kvp
        tempHashset.Clear();
        tempHashset.UnionWith(keyValuePair.Value.Select(car => car.CarBrand));

        // if tempHashset is not a subset of carBrandsInlist2and3
        // then in this keyValuePair there is a car brand that does not exist in list2 or list3
        
        return !tempHashset.IsSubsetOf(carBrandsInlist2and3);
    }));