Как обновить хеш-таблицу C# в цикле?

Я думаю, что этот вопрос требует команды МИНУС.

Select distinct(order_id)
  from {table_name}
MINUS
Select distinct(order_id)
  from (table_name}
where status = 'Complete'

Вы можете взять выходные данные из этого SQL и использовать их для дальнейших запросов, при необходимости.

10
задан Quinn Taylor 15 June 2009 в 20:18
поделиться

10 ответов

Вы могли считать набор ключей в другой экземпляр IEnumerable сначала, затем foreach по тому списку

        System.Collections.Hashtable ht = new System.Collections.Hashtable();

        ht.Add("test1", "test2");
        ht.Add("test3", "test4");

        List<string> keys = new List<string>();
        foreach (System.Collections.DictionaryEntry de in ht)
            keys.Add(de.Key.ToString());

        foreach(string key in keys)
        {
            ht[key] = DateTime.Now;
            Console.WriteLine(ht[key]);
        }
14
ответ дан 3 December 2019 в 18:36
поделиться

В понятии я сделал бы:

Hashtable table = new Hashtable(); // ps, I would prefer the generic dictionary..
Hashtable updates = new Hashtable();

foreach (DictionaryEntry entry in table)
{
   // logic if something needs to change or nog
   if (needsUpdate)
   {
      updates.Add(key, newValue);
   }
}

// now do the actual update
foreach (DictionaryEntry upd in updates)
{
   table[upd.Key] = upd.Value;
}
4
ответ дан 3 December 2019 в 18:36
поделиться

Если Вы используете Словарь вместо Хеш-таблицы, так, чтобы тип ключей был известен, самый легкий способ сделать копию набора Ключей, чтобы избежать, чтобы это исключение было:

foreach (string key in new List<string>(dictionary.Keys))

Почему Вы получаете исключение, говоря Вам, что Вы изменили набор, которого Вы выполняете итерации, когда на самом деле Вы не имеете?

Внутренне, класс Хеш-таблицы имеет поле версии. Добавление, Вставьте и Удалите инкремент методов эта версия. При создании перечислителя на любом из наборов, которые выставляет Хеш-таблица, объект перечислителя включает текущую версию Хеш-таблицы. Метод MoveNext перечислителя проверяет версию перечислителя по Хеш-таблице, и если они не равны, это бросает InvalidOperationException, который Вы видите.

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

Существуют другой, более тонкий дефект дизайна в этом подходе. Версия является Int32. Метод UpdateVersion не делает никакой проверки границ. Поэтому возможно при создании точно правильного количества модификаций к Хеш-таблице (2 раза Int32.MaxValue, плюс-минус), для версии на Хеш-таблице и перечислителе, чтобы быть тем же даже при том, что Вы радикально изменили Хеш-таблицу начиная с создания перечислителя. Таким образом, метод MoveNext не выдаст исключение даже при том, что это должно, и Вы получите неожиданные результаты.

3
ответ дан 3 December 2019 в 18:36
поделиться

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

Однако, если Вы просто пытаетесь обновить значение затем, можно записать:

deEntry.Value = sValue

Обновление значения здесь не оказывает влияния на перечислитель.

1
ответ дан 3 December 2019 в 18:36
поделиться

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

Вы используете.NET 3.5? Если так, LINQ делает вещи немного легче.

2
ответ дан 3 December 2019 в 18:36
поделиться

Это зависит от того, почему Вы - цикличное выполнение через объекты в хеш-таблице. Но Вы, вероятно, смогли бы выполнить итерации через ключи вместо этого. Так

foreach (String sKey in htSettings_m.Keys)
{   // Get value from Registry and assign to sValue.
    // ...    
    // Change value in hashtable.
    htSettings_m[sKey] = sValue;
}

Другая опция состоит в том, чтобы создать новый HashTable. Выполните итерации через первое при добавлении, что объекты к второму затем заменяют оригинал новым.
Цикличное выполнение через ключи требует меньшего количества объектных выделений все же.

0
ответ дан 3 December 2019 в 18:36
поделиться
private Hashtable htSettings_m = new Hashtable();

htSettings_m.Add("SizeWidth", "728");    
htSettings_m.Add("SizeHeight", "450");    
string sValue = "";    
foreach (string sKey in htSettings_m.Keys)    
{    
    // Get value from Registry and assign to sValue    
    // ...    
    // Change value in hashtable.    
    htSettings_m[sKey] = sValue;    
}
-1
ответ дан 3 December 2019 в 18:36
поделиться

Возможно, можно использовать Хеш-таблицу. Набор ключей? Перечисление через это могло бы быть возможным при изменении Хеш-таблицы. Но это - только предположение...

-4
ответ дан 3 December 2019 в 18:36
поделиться

Ключевой частью является метод ToArray ()

var dictionary = new Dictionary<string, string>();
foreach(var key in dictionary.Keys.ToArray())
{
    dictionary[key] = "new value";
}
2
ответ дан 3 December 2019 в 18:36
поделиться

Вот как я сделал это в словаре; сбрасывает каждое значение в dict на false:

Dictionary<string,bool> dict = new Dictionary<string,bool>();

for (int i = 0; i < dict.Count; i++)
{
    string key = dict.ElementAt(i).Key;
    dict[key] = false;
}
0
ответ дан 3 December 2019 в 18:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: