[英]How to compare IEnumerable<Dictionary<string, object>> based on matching keys in C#
我想比較兩個不同列表(源列表和目標列表)中的數據。 它們是兩個不同的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);
}
}
好的,我現在根據您的問題更新了我的答案。
您將需要一種方法來檢查字典是否相等。
下面的那個期望在兩個字典中都具有相同的鍵,這取決於您的需要,但是如果碰巧具有不同的鍵,只需在現有的等於檢查之前添加一個檢查 。
我已將其實現為擴展方法,因此更易於使用:
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,因為with foreach
更具可讀性和易於理解。
還要注意,我使用的是yield return
而不是臨時表來列出收益候選者。 如果您喜歡臨時列表,請隨時進行更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.