Какой самый быстрый способ скопировать значения и ключи из одного словаря в другой на C#?

Кажется, нет метода dictionary.AddRange (). Кто-нибудь знает, как лучше скопировать элементы в другой словарь без использования цикла foreach.

Я использую System.Collections.Generic.Dictionary. Это для .NET 2.0.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
28
0
43 937
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Есть конструктор Dictionary, который принимает еще один Dictionary.

Вам нужно будет использовать IDictionary, но есть перегрузка Add(), которая требует KeyValuePair<TKey, TValue>. Однако вы все еще используете foreach.

Спасибо за ответ, но в обоих словарях есть элементы на тот момент, когда мне нужно сделать копию.

Helephant 17.09.2008 13:54

Если вы имеете дело с двумя существующими объектами, вы можете немного поработать с методом CopyTo: http://msdn.microsoft.com/en-us/library/cc645053.aspx

Используйте метод Add другой коллекции (получателя), чтобы поглотить их.

Я не смог найти метод добавления для словаря, который принимал бы массив?

Helephant 17.09.2008 14:08

Я не понимаю, почему бы не использовать Словарь (Dictionary) (как предлагает ageektrapped).

Вы хотите выполнить мелкую или глубокую копию? (то есть оба словаря указывают на одни и те же ссылки или новые копии каждого объекта внутри нового словаря?)

Если вы хотите создать словарь новый, указывающий на объекты новый, я думаю, что единственный способ - через для каждого.

Мелкая копия - это нормально. У меня есть два словаря, которые я заполняю в методе, и я хочу скопировать второй словарь меньшего размера в первый в конце метода. Мне нужно разделять их на протяжении всего срока действия метода, потому что они означают разные вещи.

Helephant 17.09.2008 14:05
Ответ принят как подходящий

Нет ничего плохого в цикле for / foreach. В любом случае это все, что мог бы сделать гипотетический метод AddRange.

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

Ради интереса я создал этот метод расширения для словаря. По возможности это должно делать глубокую копию.

public static Dictionary<TKey, TValue> DeepCopy<TKey,TValue>(this Dictionary&lt;TKey, TValue> dictionary)
        {
            Dictionary<TKey, TValue> d2 = new Dictionary<TKey, TValue>();

            bool keyIsCloneable = default(TKey) is ICloneable;
            bool valueIsCloneable = default(TValue) is ICloneable;

            foreach (KeyValuePair<TKey, TValue> kvp in dictionary)
            {
                TKey key = default(TKey);
                TValue value = default(TValue);
                if (keyIsCloneable)
                {
                    key = (TKey)((ICloneable)(kvp.Key)).Clone();
                }

                else
                {
                    key = kvp.Key;
                }

                if (valueIsCloneable)
                {
                    value = (TValue)((ICloneable)(kvp.Value)).Clone();
                }

                else
                {
                    value = kvp.Value;
                }

                d2.Add(key, value);
            }

            return d2;
        }

var Animal = new Dictionary<string, string>();

в конструктор можно передать существующий Словарь животных.

Dictionary<string, string> NewAnimals = new Dictionary<string, string>(Animal);

Для словаря примитивного типа:

public void runIntDictionary()
{
    Dictionary<int, int> myIntegerDict = new Dictionary<int, int>() { { 0, 0 }, { 1, 1 }, { 2, 2 } };
    Dictionary<int, int> cloneIntegerDict = new Dictionary<int, int>();
    cloneIntegerDict = myIntegerDict.Select(x => x.Key).ToList().ToDictionary<int, int>(x => x, y => myIntegerDict[y]);
}

или с объектом, реализующим ICloneable:

public void runObjectDictionary()
{
    Dictionary<int, number> myDict = new Dictionary<int, number>() { { 3, new number(3) }, { 4, new number(4) }, { 5, new number(5) } };
    Dictionary<int, number> cloneDict = new Dictionary<int, number>();
    cloneDict = myDict.Select(x => x.Key).ToList().ToDictionary<int, number>(x => x, y => myDict[y].Clone());
}

public class number : ICloneable
{
    public number()
    {
    }
    public number(int newNumber)
    {
        nr = newnumber;
    }
    public int nr;

    public object Clone()
    {
        return new number() { nr = nr };
    }
    public override string ToString()
    {
        return nr.ToString();
    }
}

Другие вопросы по теме