c # - выбрать ключи и значения, которых нет в другом словаре

0

У меня к этим двум словарям:

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();
}

Итак, теперь мне нужно проверить, являются ли ключи (таблицы) одинаковыми, что таблицы доступны в обоих словарях, тогда

Мне нужно показать значение (столбцы) этого ключа (таблицы), который существует в словаре один, но не существует в словаре 2

Теги:
linq
dictionary
collections

2 ответа

0
Лучший ответ

Я не буду заверять эту работу, я ее не тестировал, и я также предполагаю, что это лучший способ сделать это, что я не знаю, или я не думал, но если бы мне пришлось это сделать, я бы сделал это это так:

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}");
    }
}
0

У меня есть FullOuterJoin расширения 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);
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню