Есть 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(), но никак не получается.
Т.к. 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();
}
}
}
}
Вы не можете расположить значения в словаре в каком-либо порядке, потому что порядок перечисления словаря не детерминирован.
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 структура, представляющая значение и его ключ. Порядок, в котором возвращаются элементы, не определен.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть террейн, на нём надо выделить область, в которой будут взрывыДопустим у нас область круг, овал, квадрат, прямоугольник или ромб
Столкнулась с проблемой того,что непрвильно определяются отрицательные числаВыводится не только первый и последние отрицательные, но и другие,которые...