我想比较两个不同列表(源列表和目标列表)中的数据。他们是两个不同的IEnumerable<Dictionary<string, object>>
我正在运行两个测试,每个测试的结果应从目标输出缺少的记录,并将缺少的记录分配给新的IEnumerable<Dictionary<string, object>>
。
两个Dictionary<string, object>
中的键始终相同。但是,列表的长度和字典中的值可能不是。
清单1:
清单2:
这是我尝试的方法,但是它仅比较列表的第一个键和值。 我想知道每个列表中的键是否有不同的值。
我的控制器:
[HttpPost]
public ActionResult TestResult(ValidationTestVM model)
{
model.NotFoundInSource = ServiceLayer.RecordCountResults(sourceQueryResults, targetQueryResults).ToList();
model.NotFoundInTarget = ServiceLayer.RecordCountResults(targetQueryResults, sourceQueryResults).ToList();
}
服务类别:
public static IEnumerable<Dictionary<string, object>> RecordCountResults(IEnumerable<Dictionary<string, object>> source, IEnumerable<Dictionary<string, object>> target)
{
var results = new List<Dictionary<string, object>>();
if((source != null && target != null) || (source.Count() > 0 && target.Count() > 0))
results = source.Where(m =>!target.Select(s => s.First().Value).Contains(m.First().Value)).ToList();
return results;
}
这似乎无法正常工作。有人可以告诉我我在做什么错吗?
创建样本数据并显示我期望如何看到退货清单的虚拟方法:
public static void DummyData(IEnumerable<Dictionary<string, object>> source, IEnumerable<Dictionary<string, object>> target)
{
// Dummy Data
List<Dictionary<string, object>> lSource = source.ToList();
List<Dictionary<string, object>> lTarget = target.ToList();
for (int i = 0; i < 3; i++)
{
var sourceDic1 = new Dictionary<string, object>();
sourceDic1.Add("Field1", "2017");
sourceDic1.Add("Field2", "2018");
sourceDic1.Add("Field3", "2019");
sourceDic1.Add("Field4", "2018_E_" + i);
lSource.Add(sourceDic1);
}
for (int i = 2; i < 4; i++)
{
var targetDic2 = new Dictionary<string, object>();
targetDic2.Add("Field1", "2017");
targetDic2.Add("Field2", "2018");
targetDic2.Add("Field3", "2019");
targetDic2.Add("Field4", "2018_E_" + i);
lTarget.Add(targetDic2);
}
// Results
var DoesNotExistInTarget = new List<Dictionary<string, object>>();
var DoesNotExistInSource = new List<Dictionary<string, object>>();
for (int i = 0; i < 2; i++)
{
var MissingDic1 = new Dictionary<string, object>();
MissingDic1.Add("Field1", "2017");
MissingDic1.Add("Field2", "2018");
MissingDic1.Add("Field3", "2019");
MissingDic1.Add("Field4", "2018_E_" + i);
DoesNotExistInTarget.Add(MissingDic1);
}
for (int i = 3; i < 4; i++)
{
var MissingDic2 = new Dictionary<string, object>();
MissingDic2.Add("Field1", "2017");
MissingDic2.Add("Field2", "2018");
MissingDic2.Add("Field3", "2019");
MissingDic2.Add("Field4", "2018_E_" + i);
DoesNotExistInSource.Add(MissingDic2);
}
}
答案 0 :(得分:1)
好的,我已经根据您的问题更新了我的答案。
您将需要一种方法来检查字典是否相等。
下面的一个期望根据需要在两个字典中具有相同的键,但是如果碰巧具有不同的键,只需在现有的相等性检查之前添加一个检查即可。
我已将其实现为扩展方法,因此更易于使用:
public static class DictionaryExtensions
{
/// <summary>
/// Expected to have 2 dictionaries with same keys
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dict1"></param>
/// <param name="dict2"></param>
/// <returns></returns>
public static bool IsEqual<T>(
this Dictionary<string, T> dict1,
Dictionary<string, T> dict2)
{
foreach (var keyValuePair in dict1)
{
if (!keyValuePair.Value.Equals(dict2[keyValuePair.Key]))
return false;
}
return true;
}
}
然后在RecordCountResult
方法中使用以下代码:
public static IEnumerable<Dictionary<string, object>> RecordCountResults(
IEnumerable<Dictionary<string, object>> source,
IEnumerable<Dictionary<string, object>> target)
{
foreach (var sourceDictionary in source)
{
var existsInTarget = false;
foreach (var targetDictionary in target)
{
if (sourceDictionary.IsEqual(targetDictionary))
{
existsInTarget = true;
break;
}
}
if (!existsInTarget)
yield return sourceDictionary;
}
}
这个想法是,您必须首先循环遍历源字典,并针对每个sourceDictionary检查目标列表中是否有匹配项。如果您的sourceDictionary在目标中不匹配,则将报告它。
我不想在RecordCountResults
方法中使用Linq,因为使用foreach
更具可读性和理解性。
还要注意,我使用的是yield return
而不是临时候选人名单。如果您喜欢临时列表,请随时进行更改。