查找两本词典之间的差异

本文关键字:之间 两本 查找 | 更新日期: 2023-09-27 18:24:52

我有两个字典,其中包含来自SAP Business 1中2个DB表的员工信息。他们有员工ID和工资,例如,我已经确保第一张和第二张表的员工ID始终是相同的

Table 1 (OHEM)
empID    salary
1        40000
2        56000
3        77000
4        80000 <------increase  

Table 2 (Salary Fitment)
empID    salary
1        40000
2        56000
3        77000
4        50000

在上面的例子中,如果4号员工的工资增加/减少(或OHEM中的任何其他员工工资变化),我想比较两个字典,然后更新表二中相应的工资。

代码

// Get service instances
var employeeService = Program.Kernel.Get<IEmployeeService>();
var salaryFitmentService = Program.Kernel.Get<ISalaryFitmentService>(); 
var OHEMDictionary = employeeService.GetAllEmployees().OrderBy(es => es.empID)
                                 .ToDictionary(od => od.empID,
                                               od => od.salary);
var SalaryFitmentDictionary = salaryFitmentService.GetAllSalaryFitments().Where(x => x.U_PD_Code.Trim().ToString() == "SYS001").OrderBy(es => es.U_Employee_ID)
                                          .ToDictionary(od => od.U_Employee_ID,
                                                              od => od.U_PD_Amount);

我已经有了更新代码。获取字典差异以便更新差异的最佳方法是什么?

查找两本词典之间的差异

类似的东西?

var diff = SalaryFitmentDictionary.Where(kv=>OHEMDictionary[kv.Key]!=kv.Value)

编辑

您还可以附加以获得每个员工的差异

.Select(kv => new { ID = kv.Key, Amount = OHEMDictionary[kv.Key] - kv.Value })

这是一个直接但方便的函数:

private static Dictionary<string, string> DiffDictionary(Dictionary<string, string> first, Dictionary<string, string> second)
{
    var diff = first.ToDictionary(e => e.Key, e => "removed");
    foreach (var other in second)
    {
        string firstValue;
        if (first.TryGetValue(other.Key, out firstValue))
        {
            diff[other.Key] = firstValue.Equals(other.Value) ? "same" : "different";
        }
        else
        {
            diff[other.Key] = "added";
        }
    }
    return diff;
}

特别是如果你只想报告变化的类型:

var first = new Dictionary<string, string>() { { "one", "two" }, { "three", "four" }, { "five", "six" } };
var second = new Dictionary<string, string>() { { "one", "2" }, { "five", "six" }, { "seven", "eight" } };
foreach (var entry in DiffDictionary(first, second))
{
    Console.WriteLine("{0} {1} ", entry.Key, entry.Value);
}

这就产生了

one different
three removed
five same
seven added

没有足够的信息来覆盖所有的基(例如:一个字典中的键是另一个字典上的键的严格子集吗?或者两个字典的键的数量和值完全相同?),但通常这就是我们所说的:

foreach(var pair in SalaryFitmentDictionary)
{
    if(OHEMDictionary[pair.Key] != pair.Value)
    {
        // This employee's salary has changed
        OHEMDictionary[pair.Key] = pair.Value;
    }
}

创建一个包含差异的类:

public class DictionaryDifference<TKey, TValue>
{
    public TKey Key
    {
        get;
        set;
    }
    public TValue OriginalValue
    {
        get;
        set;
    }
    public TValue NewValue
    {
        get;
        set;
    }
}

创建一个扩展方法来查找差异:

public static class DictionaryExtensions
{
    public static IEnumerable<DictionaryDifference<TKey, TValue>> GetDifferencesFrom<TKey, TValue>(
        this IDictionary<TKey, TValue> original,
        IDictionary<TKey, TValue> latest)
        where TValue : IComparable
    {
        foreach (var originalItem in original)
        {
            if (latest.ContainsKey(originalItem.Key))
            {
                if (originalItem.Value.CompareTo(latest[originalItem.Key]) != 0)
                {
                    // The key is in the latest but the value is different.
                    yield return new DictionaryDifference<TKey, TValue>
                    {
                        Key = originalItem.Key,
                        OriginalValue = originalItem.Value,
                        NewValue = latest[originalItem.Key]
                    };
                }
            }
            else
            {
                // The key is not in the latest dictionary.
                yield return new DictionaryDifference<TKey, TValue>
                {
                    Key = originalItem.Key,
                    OriginalValue = originalItem.Value,
                    NewValue = default(TValue)
                };
            }
        }
        foreach (var newItem in latest)
        {
            if (!original.ContainsKey(newItem.Key))
            {
                // The key is not in the original dictionary.
                yield return new DictionaryDifference<TKey, TValue>
                {
                    Key = newItem.Key,
                    OriginalValue = default(TValue),
                    NewValue = latest[newItem.Key]
                };
            }
        }
    }
}

创建2个字典并进行比较:

var dictionary1 = new Dictionary<int, double>();
dictionary1.Add(1, 40000);
dictionary1.Add(2, 56000);
dictionary1.Add(3, 77000);
dictionary1.Add(4, 80000);
dictionary1.Add(5, 100000);
var dictionary2 = new Dictionary<int, double>();
dictionary2.Add(1, 40000);
dictionary2.Add(2, 56000);
dictionary2.Add(3, 77000);
dictionary2.Add(4, 50000);
dictionary2.Add(6, 35000);
foreach (var difference in dictionary1.GetDifferencesFrom(dictionary2))
{
    Console.WriteLine(
        "Key {0} was {1} but is now {2}",
        difference.Key.ToString(),
        difference.OriginalValue.ToString(),
        difference.NewValue.ToString());
}

输出:

Key 4 was 80000 but is now 50000
Key 5 was 100000 but is now 0
Key 6 was 0 but is now 35000
   var result = from o in OHEMDictionary
                 join f in SalaryFitmentDictionary on o.Key equals f.Key
                 where o.Value != f.Value
                 select { o.Key, o.Value - f.Value};

这将只涵盖出现在两个字典中的项目,但您可以这样做:

Dictionary<int, string> first = new Dictionary<int, string> 
       { { 1, "One" }, { 2, "Two" }, { 3, "Three" } };
Dictionary<int, string> second = new Dictionary<int, string> 
       { { 1, "One" }, { 2, "Two" }, { 3, "Tri" } };
var difference = from f in first
                 join s in second on f.Key equals s.Key
                 where f.Value != s.Value
                 select new {Key = f.Key, 
                             FirstValue = f.Value, 
                             SecondValue = s.Value };
foreach (var item in difference)
{
    Console.WriteLine("Different item with key {0}, Values {1} and {2}", 
                          item.Key, item.FirstValue, item.SecondValue);
}