[英]Best way to find values not in two lists c#
I have two lists which I need to compare (carOptions and custOptions). 我有两个列表需要比较(carOptions和custOptions)。 Both of these lists are in my Customer class like below:
这两个列表都在我的Customer类中,如下所示:
public class CustomerDTO
{
public int CustomerId { get; set; }
//other props removed for brevity
public List<OptionDTO> SelectedCarOptions { get; set; }
public List<OptionDTO> SelectedCustomerOptions { get; set; }
}
var existingData = _myRepository.GetDataByCustomer(customerId, year);
var existingCarOptions = existingData.Select(f => f.SelectedCarOptions);
var existingCustomerOptions = existingData.Select(f => f.SelectedCustomerOptions);
existingData is an IEnumerable of CustomerDTO and then existingCarOptions and existingCustomerOptions is an IEnumerable<List<OptionDTO>>
existingData是CustomerDTO的IEnumerable,然后existingCarOptions和existingCustomerOptions是
IEnumerable<List<OptionDTO>>
In the method, I have a list of IEnumerable<OptionDTO>
options that gets passed in. I then break this down into car or customer based on the Enum as below: 在该方法中,我有一个
IEnumerable<OptionDTO>
的IEnumerable<OptionDTO>
选项列表。然后,我根据枚举将其分为汽车或客户,如下所示:
var newCarOptions = options.Where(o => o.OptionTypeID == OptionType.CarOptions);
var newCustomerOptions = options.Where(o => o.OptionTypeID == OptionType.CustomerOptions).ToList();
What I need to do is find which options are in one collection but no in the other. 我需要做的是找到哪些选项在一个集合中,而在其他集合中则没有。
I tried as below but getting an Error on the Except (I maybe need to create my own static method in that class) but I am not sure this is the best approach really? 我尝试如下,但在Except上遇到错误(我可能需要在该类中创建自己的静态方法),但是我不确定这是否是最好的方法吗?
if (existingCarOptions.Count() != newCarOptions.Count())
{
//var test = newCarOptions.Except(existingCarOptions);
}
if (existingCustomerOptions.Count() != newCustomerOptions.Count())
{
//var test2 = newCustomerOptions.Except(existingCustomerOptions);
}
Is it also quite a bit of code in the method - I could split it out into sperate methods if required but perhaps there is a simpler way I could achieve this? 方法中是否还包含大量代码-如果需要,我可以将其拆分为单独的方法,但是也许有一种更简单的方法可以实现此目的?
If you want to compare two classes you can use IEqualityComparer
如果要比较两个类,可以使用
IEqualityComparer
public class OptionComparer : IEqualityComparer<OptionDTO>
{
public bool Equals(OptionDTO x, OptionDTO y)
{
if (object.ReferenceEquals(x, y))
{
return true;
}
if (object.ReferenceEquals(x, null) ||
object.ReferenceEquals(y, null))
{
return false;
}
return x.OptionTypeID == y.OptionTypeID ;
}
public int GetHashCode(OptionDTO obj)
{
if (obj == null)
{
return 0;
}
return obj.OptionTypeID.GetHashCode();
}
With using this you can ıdentify that What is the concept of equality for these classes. 使用此方法,您可以确定这些类的相等概念是什么。
Now we can find different values.. 现在我们可以找到不同的值。
public List<OptionDTO>CalculateDiffBetweenLists(List<OptionDTO> left, List<OptionDTO> right){
List<OptionDTO> optionDiff;
optionDiff = left.Except(right, new OptionComparer ()).ToList();
return optionDiff ;
}
I'm assuming OptionDTO
has a property called Id
, which uniquely identifies an option (you have to change the code accordingly if this is not the case), you may use HashSet
s to quickly find unmatched OptionsDTO
s, while keeping the overall time cost O(n)
(where n is the max number of combined options). 我假设
OptionDTO
具有一个名为Id
的属性,该属性唯一地标识一个选项(如果不是这种情况,则必须相应地更改代码),可以使用HashSet
来快速查找不匹配的OptionsDTO
,同时保持整体时间成本O(n)
(其中n是组合选项的最大数量)。
Create the existing options sets: 创建现有的选项集:
var existingCarOptions = existingData.SelectMany(d => d.SelectedCarOptions).Select(o => o.Id);
var existingCustomerOptions = existingData.SelectMany(d => d.SelectedCustomerOptions).Select(o => o.Id);
var existingCarOptionsIds = new HashSet<int>(existingCarOptions);
var existingCustomerOptionsIds = new HashSet<int>(existingCustomerOptions );
Then you extract options missing in existing sets with: 然后,使用以下命令提取现有集中缺少的选项:
var unmatchedCarOptions = newCarOptions.Where(o => !existingCarOptionsIds.Contains(o.Id));
var unmatchedCustomerOptions = newCustomerOptions.Where(o => !existingCustomerOptionsIds.Contains(o.Id));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.