在 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);
}));
我无法同时使用 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);
}));