【问题标题】:c#- select keys and values that does not exist in another dictionaryc#- 选择另一个字典中不存在的键和值
【发布时间】:2018-05-27 10:46:20
【问题描述】:

我有这两个词典:

Dictionary<string, List<string>> dictionary_1 = new Dictionary<string, List<string>> { };
Dictionary<string, List<string>> dictionary_2 = new Dictionary<string, List<string>> { };

两个字典中的键和值都是(表和列):

DataTable old_database_columns = new DataTable();
DataTable new_database_columns = new DataTable();
list_of_table_of_old_database = db.Select("", "", "", "", "", "", "", "", "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.tables WHERE TABLE_SCHEMA = '" + old_database.Text.Trim() + "' ", "");
list_of_table_of_current_database = db.Select("", "", "", "", "", "", "", "", "SELECT TABLE_NAME FROM INFORMATION_SCHEMA.tables WHERE TABLE_SCHEMA = '" + new_database.Text.Trim() + "' ", "");

List<string> table_list_old_database = new List<string> { };
List<string> table_list_new_database = new List<string> { };
for (i = 0; i < list_of_table_of_old_database.Rows.Count; i++) {
     table_list_old_database.Add(list_of_table_of_old_database.Rows[i][0].ToString());  
}
for (i = 0; i < list_of_table_of_current_database.Rows.Count; i++) {
   table_list_old_database.Add(list_of_table_of_old_database.Rows[i][0].ToString());
}
for (j = 0; j < table_list_old_database.Count; j++)
{
    old_database_columns = db.Select("", "", "", "", "", "", "", "", "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.columns WHERE TABLE_SCHEMA = '" + old_database.Text.Trim() + "' and TABLE_NAME = '" + table_list_old_database[j].ToString() + "' ", "");
    for (i = 0; i < old_database_columns.Rows.Count; i++)
    {
        old_database_columns_list.Add(old_database_columns.Rows[i][0].ToString());        
    }
    dictionary_1.Add(table_list_old_database[j], new List<string>(old_database_columns_list));
    old_database_columns_list.Clear();
}

for (j = 0; j < table_list_new_database.Count; j++)
{
    new_database_columns = db.Select("", "", "", "", "", "", "", "", "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.columns WHERE TABLE_SCHEMA = '" + new_database.Text.Trim() + "' and TABLE_NAME = '" + table_list_new_database[j].ToString() + "' ", "");
    for (i = 0; i < new_database_columns.Rows.Count; i++)
    {
        new_database_columns_list.Add(new_database_columns.Rows[i][0].ToString());
    }
    dictionary_2.Add(table_list_new_database[j] , new List<string>(new_database_columns_list));
    new_database_columns_list.Clear();
}

所以现在我需要检查键(表)是否相同意味着表在两个字典中都可用

我需要显示存在于字典 1 中但不存在于字典 2 中的键(表)的值(列)

【问题讨论】:

  • 谁能指导我如何编写正确的条件,以便我可以排除两个字典中的值
  • 您在寻找ExceptIntersect吗?
  • 字典一中可用而字典二中不可用的项目除外

标签: c# mysql linq dictionary collections


【解决方案1】:

我不会保证这项工作,我没有测试它,我还假设有更好的方法来做我不知道或我没有考虑过,但如果我必须这样做,我会这样做:

Dictionary<string, List<string>> dictionary_1 = new Dictionary<string, List<string>> { };
Dictionary<string, List<string>> dictionary_2 = new Dictionary<string, List<string>> { };

// Fill those dictionaries...

// Check for non existing things in dictionary 2 but existing in 1
foreach (KeyValuePair<String, List<String>> _element in dictionary_1)
{
    List<String> _valuesFrom2;
    // Check if table exist
    if (dictionary_2.TryGetValue(_element.Key, out _valuesFrom2))
    {
        //Check if column exist
        foreach (String _value in _element.Value)
        {
            if (!_valuesFrom2.Contains(_value))
            {
                Console.WriteLine($"Dictionary 2, table {_element.Key} does not contain {_value}");
            }
        }
    }
    else
    {
        Console.WriteLine($"Dictionnary 2 does not contain : {_element.Key}");
    }
}

【讨论】:

    【解决方案2】:

    我有一个FullOuterJoin linq 扩展方法,可以方便地进行此类操作。然后就可以了

    var lookup =
        dictionary_1.Keys
            .FullOuterJoin(
                dictionary_2.Keys,
                key1 => key1,
                key2 => key2,
                (key1, key2) => new { key1, key2 })
            .ToLookup(x =>
                x.key1 != null && x.key2 != null
                    ? "both"
                    : x.key1 != null
                        ? "dic1"
                        : "dic2",
                x => x.key1 ?? x.key2);
    var keysExclusivelyInDic1 = lookup["dic1"];
    var keysExclusivelyInDic2 = lookup["dic2"];
    var keysThatMatch = lookup["both"];
    

    扩展方法FullOuterJoin的实现是:

    public static class JoinExtensions
    {
        public static IEnumerable<TResult> FullOuterGroupJoin<TLeft, TRight, TKey, TResult>(
            this IEnumerable<TLeft> leftSeq,
            IEnumerable<TRight> rightSeq,
            Func<TLeft, TKey> keySelectorLeft,
            Func<TRight, TKey> keySelectorRight,
            Func<IEnumerable<TLeft>, IEnumerable<TRight>, TKey, TResult> projectionSelector,
            IEqualityComparer<TKey> comparer = null)
        {
            comparer = comparer ?? EqualityComparer<TKey>.Default;
            var leftLookup = leftSeq.ToLookup(keySelectorLeft, comparer);
            var rightLookup = rightSeq.ToLookup(keySelectorRight, comparer);
            var keys = new HashSet<TKey>(leftLookup.Select(g => g.Key), comparer);
            keys.UnionWith(rightLookup.Select(g => g.Key));
            var join = keys
                .Select(key => projectionSelector(leftLookup[key], rightLookup[key], key));
            return join;
        }
    
        public static IEnumerable<TResult> FullOuterJoin<TLeft, TRight, TKey, TResult>(
            this IEnumerable<TLeft> leftSeq,
            IEnumerable<TRight> rightSeq,
            Func<TLeft, TKey> keySelectorLeft,
            Func<TRight, TKey> keySelectorRight,
            Func<TLeft, TRight, TKey, TResult> projectionSelector,
            TLeft defaultLeft = default(TLeft),
            TRight defaultRight = default(TRight),
            IEqualityComparer<TKey> comparer = null)
        {
            comparer = comparer ?? EqualityComparer<TKey>.Default;
            var leftLookup = leftSeq.ToLookup(keySelectorLeft, comparer);
            var rightLookup = rightSeq.ToLookup(keySelectorRight, comparer);
    
            var keys = new HashSet<TKey>(leftLookup.Select(g => g.Key), comparer);
            keys.UnionWith(rightLookup.Select(g => g.Key));
    
            var join = keys
                .SelectMany(
                    key => leftLookup[key].DefaultIfEmpty(defaultLeft),
                    (key, leftItem) => new { key, leftItem })
                .SelectMany(
                    leftItemAndKey => 
                        rightLookup[leftItemAndKey.key]
                            .DefaultIfEmpty(defaultRight),
                    (leftItemAndKey, rightItem) =>
                        projectionSelector(
                            leftItemAndKey.leftItem, 
                            rightItem, 
                            leftItemAndKey.key));
    
            return join;
        }
    
        public static IEnumerable<TResult> FullOuterJoin<TLeft, TRight, TKey, TResult>(
            this IEnumerable<TLeft> leftSeq,
            IEnumerable<TRight> rightSeq,
            Func<TLeft, TKey> keySelectorLeft,
            Func<TRight, TKey> keySelectorRight,
            Func<TLeft, TRight, TResult> projectionSelector,
            TLeft defaultLeft = default(TLeft),
            TRight defaultRight = default(TRight),
            IEqualityComparer<TKey> comparer = null)
        {
            return leftSeq
                .FullOuterJoin(
                    rightSeq,
                    keySelectorLeft,
                    keySelectorRight,
                    (leftItem, rightItem, _) => projectionSelector(leftItem, rightItem),
                    defaultLeft,
                    defaultRight,
                    comparer);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 2011-02-27
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      相关资源
      最近更新 更多