public class ReplaceSubstring
{
public string Name { get; set; }
public string Value { get; set; }
}
Как правильно написать алгоритм, чтобы получить Dictionary<string,string> или массив тех же ReplaceSubstring, где значения взаимно уже раскрыты и кольцевые ссылки обработаны (поднятием исключения)?
Здравствуйте, matumba, Вы писали:
I>>Есть такой XML-файл: I>>Как правильно написать алгоритм M>Если "правильно", то только головой! M>Мы услышали саму задачу. В чём состоит ВАША ПРОБЛЕМА, что вы даже не пытаетесь её решить?
Пытаюсь, но не уверен, что правильно. Изначальная проблема в том, что в конфигурационном XML-файле надо задать много строк, в частности, в качестве значений атрибутов, в которых (в этих строках) часто повторяются подстроки. Например так:
Вот в этих Attr1, Attr2, Attr3 и т.п. значения — строки, пути к ресурсам. Пути к ресурсам часто повторяются, и могут иметь вообще разный смысл, семантически неопределенный, по типу строки-моникера в COM.
Решил сделать в этом конфигурационном файле такую секцию, как в ТС, а повтоворяющиеся подстроки в Attr1, Attr2, Attr3 и т.п. заменить на ключи этих подстрок. Вот, собственно, и все.
Здравствуйте, Ilinichev, Вы писали:
I>Как правильно написать алгоритм, чтобы получить Dictionary<string,string> или массив тех же ReplaceSubstring, где значения взаимно уже раскрыты и кольцевые ссылки обработаны (поднятием исключения)?
Я бы позаимствовал общую логику у environment variables — порядок определения важен, каждая строка обрабатывается сразу при прочтении.
Тогда ваша проблема сводится к последовательной обработке каждой строки и написанию ReplaceMany.
P.S. Dictionary отпадает сразу — он не гарантирует порядок хранения элементов.
Здравствуйте, Ilinichev, Вы писали:
I><MyCfgFile> I> <MyCfgSection> I> <MyCfgTag Attr1="" Attr2="" Attr3="" />
I>Вот в этих Attr1, Attr2, Attr3 и т.п. значения — строки, пути к ресурсам. Пути к ресурсам часто повторяются
Хех, так вы пытаетесь уменьшить размер конфига — это главная задача?
Здравствуйте, matumba, Вы писали:
I>>Вот в этих Attr1, Attr2, Attr3 и т.п. значения — строки, пути к ресурсам. Пути к ресурсам часто повторяются
M>Хех, так вы пытаетесь уменьшить размер конфига — это главная задача?
1. Создаем Dictionary<Name, Value>, у которого в Value не раскрытые ссылки на ReplaceSubstring
2. Делаем все возможные раскрытия
Для каждого Value, каждую ссылку на ReplaceSubstring заменяем на соответствующее ReplaceSubstring.Value (после замены, идем к следующей ссылке на ReplaceSubstring (вглубь не идем))
3. Остались не раскрытые значения? Возвращаемся к шагу 2.
ReplaceSubstring.Value ссылается само на себя -> эксепшен — кольцевая ссылка.
Такой подход не требует жесткого порядка следования ReplaceSubstring'ов
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания http://rsdn.ru/Info/rules.xml
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания http://rsdn.ru/Info/rules.xml
Re[2]: Многопроходное разрешение (раскрытие) ссылок
Здравствуйте, igor-booch, Вы писали:
IB>1. Создаем Dictionary<Name, Value>, у которого в Value не раскрытые ссылки на ReplaceSubstring IB>2. Делаем все возможные раскрытия IB>Для каждого Value, каждую ссылку на ReplaceSubstring заменяем на соответствующее ReplaceSubstring.Value (после замены, идем к следующей ссылке на ReplaceSubstring (вглубь не идем)) IB>3. Остались не раскрытые значения? Возвращаемся к шагу 2.
Интересно, а как можно узнать, остались не раскрытые значения или нет? Я использовал условие "если не произошло ни одного раскрытия в п.2, прекращаем цикл while(true)".
IB>ReplaceSubstring.Value ссылается само на себя -> эксепшен — кольцевая ссылка. IB>Такой подход не требует жесткого порядка следования ReplaceSubstring'ов
Я вот сам не понял, почему мне уперлось, не требовать жесткого порядка, т.к. на самом деле это ничего не дает — кольцевые ссылки так или иначе невозможно обойти, а вот увидеть их глазами в конфигурации сложнее. На самом деле, теперь я увидел, что требовать жесткого порядка гораздо читабельнее получается, т.к. отлаживать человеку гораздо легче, если что пойдет не так.
Re[3]: Многопроходное разрешение (раскрытие) ссылок
I>Интересно, а как можно узнать, остались не раскрытые значения или нет? Я использовал условие "если не произошло ни одного раскрытия в п.2, прекращаем цикл while(true)".
Можно и так.
IB>>Такой подход не требует жесткого порядка следования ReplaceSubstring'ов I>Я вот сам не понял, почему мне уперлось, не требовать жесткого порядка, т.к. на самом деле это ничего не дает — кольцевые ссылки так или иначе невозможно обойти, а вот увидеть их глазами в конфигурации сложнее. На самом деле, теперь я увидел, что требовать жесткого порядка гораздо читабельнее получается, т.к. отлаживать человеку гораздо легче, если что пойдет не так.
Да, будет читабельней. Хотя если Вам потребуется разбить ReplaceSubstring'и по смысловым группам и наиболее важные смысловые группы поместить в начало порядок может быть нарушен.
Добавление ReplaceSubstring и изменение ReplaceSubstring.Value будет дороже и сложнее, если требуется строгий порядок. Хотя я предполагаю, что чтение у Вас будет намного чаще, чем запись и вряд ли производительность записи в конфиг критична. Дороговизна записи зависит от среднего количества ссылок на один ReplaceSubstring.
Еще это может пригодиться, если у Вас уже есть большие конфиги с неупорядоченными ReplaceSubstring'ами. Хотя можно можно написать прогу, которая их упорядочит, но это дополнительный геморрой при деплое.
Отвечайте на это сообщение, только если у Вас хорошее настроение и в Вашем ответе планируются только конструктивные вопросы и замечания http://rsdn.ru/Info/rules.xml
AVK>Реализацию Subst и отслеживание циклических ссылок оставляю тебе.
Не приходилось еще использовать этот Lazy'T. Идея интересная, но у меня такое ощущение, что оно уйдет в бесконечный цикл даже если не будет никаких циклических ссылок в подстроках. Сейчас попробую.
AVK>Реализацию Subst и отслеживание циклических ссылок оставляю тебе.
Нет, не понимаю, не вижу смысла. Смысл есть только в одном случае, когда формат заменяемых подстрок известен, например, {key}, тогда при первом доступе к значению можно увидеть, что надо найти значения и вставить их в placeholder-ы, а значения раскручивать дальше. Но в моём случае формат заменяемых подстрок неизвестен, поэтому, если я правильно конечно же всё понял, Lazy<T> не дает никаких преимуществ, только запутывает всё. Или я не прав?
Здравствуйте, Ilinichev, Вы писали:
I>Не приходилось еще использовать этот Lazy'T. Идея интересная, но у меня такое ощущение, что оно уйдет в бесконечный цикл даже если не будет никаких циклических ссылок в подстроках.
Если не будет — не уйдет. А вот циклические ссылки надо отслеживать.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
Здравствуйте, Ilinichev, Вы писали:
I>Нет, не понимаю, не вижу смысла.
Что не понимаешь?
I> Смысл есть только в одном случае, когда формат заменяемых подстрок известен, например, {key}, тогда при первом доступе к значению можно увидеть, что надо найти значения и вставить их в placeholder-ы, а значения раскручивать дальше. Но в моём случае формат заменяемых подстрок неизвестен
Тут уже я нифига не понял из этой фразы.
I>, поэтому, если я правильно конечно же всё понял, Lazy<T> не дает никаких преимуществ, только запутывает всё. Или я не прав?
Вопрос не понятен. Какие преимущества ты ищешь у Lazy<T> и зачем? Lazy<T> просто позволяет ресолвить по требованию. В реальности лучше кешик, но в фреймворке готовых классов таких нет, поэтому для простоты в примере использован Lazy.
... << RSDN@Home 1.2.0 alpha 5 rev. 99 on Windows 8 6.2.9200.0>>
Здравствуйте, AndrewVK, Вы писали:
I>> Смысл есть только в одном случае, когда формат заменяемых подстрок известен, например, {key}, тогда при первом доступе к значению можно увидеть, что надо найти значения и вставить их в placeholder-ы, а значения раскручивать дальше. Но в моём случае формат заменяемых подстрок неизвестен AVK>Тут уже я нифига не понял из этой фразы. AVK>Lazy<T> просто позволяет ресолвить по требованию.
Спасибо, разобрался. Я имел в виду, что как только ты захочешь разресолвить случайно выбранный элемент из множества первый раз, придется в общем случае автоматом ресолвить все остальные элементы. Вот если ввести формат заменяемых подстрок, например, ключи — они в фигурных скобках — {key} или в символах процента — %key%, тогда бы при ресолве любого элемента можно было бы построить дерево и ресолвить не все множество элементов, а только те, ключи которых указаны в исходном значении запрошенного элемента. Да, в таком случае получается преимущество. И, каюсь, прошу прощения, только сейчас обратил внимание на то, что в примере ТС написал как раз так, как-будто формат заменяемых подстрок оговорен, а сам все время исходил из того, что он не определен, т.е вот из этого: