Соединить 2 словаря поочередно

209
26 июля 2021, 13:20

Есть 2 словаря типа Dictionary<string, Person>, например:

1 словарь: 
dict1["test1"].Add(new Person{Name = "Tom", Age = "29"});            
dict1["test2"].Add(new Person{Name = "Artem", Age = "30"});
dict1["test3"].Add(new Person{Name = "Kirill", Age = "15"});
2 словарь: 
dict_2["test_8"].Add(new Person{Name = "Valeria", Age = "47"});            
dict_2["test2"].Add(new Person{Name = "Katya", Age = "20"});
dict_2["test_47"].Add(new Person{Name = "Polina", Age = "30"});

Мне необходимо объединить эти два словаря в один общий, чтобы значения чередовались, например:

3 словарь: 
dict1["test1"].Add(new Person{Name = "Tom", Age = "29"});
dict_2["test_8"].Add(new Person{Name = "Valeria", Age = "47"});            
dict1["test2"].Add(new Person{Name = "Artem", Age = "30"});
dict_2["test2"].Add(new Person{Name = "Katya", Age = "20"});
dict1["test3"].Add(new Person{Name = "Kirill", Age = "15"});       
dict_2["test_47"].Add(new Person{Name = "Polina", Age = "30"});

Может быть такое, что ключи будут одинаковые и в этом случае данные из второго словаря добавлялись в конец первого. Пробовал через функцию Zip(), но никак не получается.

Answer 1

Т.к. Dictionary - неупорядоченная коллекция и в ней могут содержаться только уникальные ключи, то я предлагаю переделать коллекции на List<KeyValuePair> и использовать какой-нибудь такой метод объединения:

public static IEnumerable<TSource> MyMerge<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
    if (first == null) throw new ArgumentException("First argument is null");
    if (second == null) throw  new ArgumentException("Second argument is null");
    using (var firstEnumerator = first.GetEnumerator())
    using (var secondEnumerator = second.GetEnumerator())
    {
        var firstMoved = firstEnumerator.MoveNext();
        var secondMoved = secondEnumerator.MoveNext();
        while (firstMoved && secondMoved)
        {
            yield return firstEnumerator.Current;
            yield return secondEnumerator.Current;
            firstMoved = firstEnumerator.MoveNext();
            secondMoved = secondEnumerator.MoveNext();
        }
        if (firstMoved)
        {
            do
            {
                yield return firstEnumerator.Current;
            } while (firstEnumerator.MoveNext());
        }
        else if (secondMoved)
        {
            do
            {
                yield return secondEnumerator.Current;
            } while (secondEnumerator.MoveNext());
        }
    }
}

Код расширения написан на коленке, скорее всего можно это сделать аккуратней.

Можно так, код короче, но с двойной проверкой

public static IEnumerable<TSource> MyMerge<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second)
{
    if (first == null) throw new ArgumentException("First argument is null");
    if (second == null) throw  new ArgumentException("Second argument is null");
    using (var firstEnumerator = first.GetEnumerator())
    using (var secondEnumerator = second.GetEnumerator())
    {
        var firstMoved = firstEnumerator.MoveNext();
        var secondMoved = secondEnumerator.MoveNext();
        while (firstMoved || secondMoved)
        {
            if (firstMoved)
            {
                yield return firstEnumerator.Current;
                firstMoved = firstEnumerator.MoveNext();
            }
            if (secondMoved)
            {
                yield return secondEnumerator.Current;
                secondMoved = secondEnumerator.MoveNext();
            }
        }
    }
}
Answer 2

Вы не можете расположить значения в словаре в каком-либо порядке, потому что порядок перечисления словаря не детерминирован.

https://docs.microsoft.com/ru-ru/dotnet/api/system.collections.generic.dictionary-2?view=netframework-4.8#комментарии

For purposes of enumeration, each item in the dictionary is treated as a KeyValuePair structure representing a value and its key. The order in which the items are returned is undefined.

В целях перечисления каждый элемент словаря рассматривается как KeyValuePair структура, представляющая значение и его ключ. Порядок, в котором возвращаются элементы, не определен.

READ ALSO
NPOI Excell merged region

NPOI Excell merged region

Есть код для формирования Excell документа

246
Как обработать ошибку в Blazor от Web Api

Как обработать ошибку в Blazor от Web Api

Всем привет! Есть два приложения:

281
Как выделить область в режиме редактирования, на террейне?

Как выделить область в режиме редактирования, на террейне?

Есть террейн, на нём надо выделить область, в которой будут взрывыДопустим у нас область круг, овал, квадрат, прямоугольник или ромб

169
Отсортировать массив между первым и последним отрицательным элементом по возрастанию

Отсортировать массив между первым и последним отрицательным элементом по возрастанию

Столкнулась с проблемой того,что непрвильно определяются отрицательные числаВыводится не только первый и последние отрицательные, но и другие,которые...

211