簡體   English   中英

如何比較IEnumerable <Dictionary<string, object> &gt;基於C#中的匹配鍵

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM