![]() |
#10 |
Участник
|
Цитата:
все равно что-то не то. адаптировал метод класса в job'ик. плюс добавил человеческий вывод в инфолог. задал множества {1,2} и {2,3} получил срабатывание assert + странные результаты. и все-таки: почему последовательно, а не в одной транзакции? может все-таки добавить поле с новым значением, и тупо заменить у каждой записи? X++: /// <summary> /// возвращает список пар [исходное значение, новое значение] для последовательной замены исходных значений на /// новые таким образом, чтобы на любом шаге замены в изменяемом множестве значений не возникало дубликатов /// может использоваться, к примеру, для перебивки значений поля таблицы, на котором висит уникальный индекс /// </summary> /// <param name="_setOfValues2Replace"> /// множество значений, подлежащих замене /// должно быть непустым и иметь простой значимый (не ссылочный) базовый тип /// </param> /// <param name="_setOfNewValues"> /// множество новых значений, на которые надо заменить исходные /// может полностью или частично пересекаться со значениями, подлежащими замене /// должно иметь тот же базовый тип и число элементов, что и _setOfValues2Replace /// </param> /// <returns> /// список контейнеров [исходное значение, новое значение] для последовательной замены в нужном порядке /// либо пустой список, если замена невозможна (к примеру, множества исходных и новых значений тождественны) /// </returns> /// <remarks> /// ACHTUNG!!! исходные множества изменяются! /// </remarks> /// <exception cref="Exception::Error"> /// выбрасывается, если входные параметры не соответствуют предусловиям /// </exception> static void DEV_getListOfValueReplacementPairs(Args args) { Set _setOfValues2Replace = new Set(Types::Integer); Set _setOfNewValues = new Set(Types::Integer); Set setOfUniqueNewValues; Set setOfCommonValues; SetIterator setIterNew; SetIterator setIterOld; anytype oldValue; anytype newValue; Types baseType; Counter nElements; List ret; ; ////////////////// /**/ _setOfValues2Replace.add(1); _setOfNewValues.add(2); _setOfValues2Replace.add(2); _setOfNewValues.add(1); /* _setOfValues2Replace.add(0); _setOfNewValues.add(1); _setOfValues2Replace.add(1); _setOfNewValues.add(2); _setOfValues2Replace.add(3); _setOfNewValues.add(3); _setOfValues2Replace.add(7); _setOfNewValues.add(4); _setOfValues2Replace.add(9); _setOfNewValues.add(5); _setOfValues2Replace.add(15); _setOfNewValues.add(6); _setOfValues2Replace.add(20); _setOfNewValues.add(7); */ ////////////////// if (_setOfValues2Replace) { baseType = _setOfValues2Replace.typeId(); nElements = _setOfValues2Replace.elements(); } // проверка предусловий if (!( _setOfNewValues && _setOfValues2Replace && nElements > 0 && nElements == _setOfNewValues.elements() && baseType == _setOfNewValues.typeId() && ( baseType == Types::Date || baseType == Types::Enum || baseType == Types::Guid || baseType == Types::Int64 || baseType == Types::Integer || baseType == Types::Real || baseType == Types::RString || baseType == Types::String || baseType == Types::Time || baseType == Types::UtcDateTime || baseType == Types::VarString ) )) { throw error( Error::wrongUseOfFunction( funcname() ) ); } ret = new List( Types::Container ); setOfCommonValues = Set::intersection( _setOfValues2Replace, _setOfNewValues ); if (setOfCommonValues.elements() < nElements) { if (!setOfCommonValues.empty()) { setOfUniqueNewValues = Set::difference( _setOfNewValues, setOfCommonValues ); setIterNew = new SetIterator( setOfUniqueNewValues ); setIterOld = new SetIterator( setOfCommonValues ); while (setIterNew.more()) { if (!setIterOld.more()) { break; } oldValue = setIterOld.value(); newValue = setIterNew.value(); ret.addEnd( [ oldValue, newValue ] ); _setOfNewValues.remove( newValue ); _setOfValues2Replace.remove( oldValue ); setOfUniqueNewValues.remove( newValue ); if (_setOfNewValues.in( oldValue )) { setOfUniqueNewValues.add( oldValue ); setIterNew.begin(); } else { setIterNew.next(); } setIterOld.next(); } Debug::assert( _setOfValues2Replace.elements() == setOfUniqueNewValues.elements() ); } else { setIterNew = new SetIterator( _setOfNewValues ); } // оставшиеся на замену значения никак не пересекаются с новыми setIterNew.begin(); setIterOld = new SetIterator( _setOfValues2Replace ); while (setIterNew.more() && setIterOld.more()) { oldValue = setIterOld.value(); newValue = setIterNew.value(); ret.addEnd( [ oldValue, newValue ] ); setIterNew.next(); setIterOld.next(); } Debug::assert( ret.elements() == nElements ); } info(ret.definitionString()); info(ret.xml()); } Последний раз редактировалось mazzy; 23.11.2010 в 02:06. Причина: поправил код согласно исправлениям gl00mie |
|
Теги |
законченный пример, уникальность |
|
![]() |
||||
Тема | Ответов | |||
Универсальный изменятель значений полей | 17 |
|