🌳 A1sDS.GetOrInsertPath()

Создавайте вложенные структуры автоматически — без проверок и циклов

⚠️ Проблема: создание вложенных структур — это ад проверок

Каждый раз приходится проверять существование каждого уровня вложенности:

❌ Обычный код (12 строк)
Настройки = Новый Структура();

Если НЕ Настройки.Свойство("ui") Тогда
    Настройки.Вставить("ui", Новый Структура());
КонецЕсли;

Если НЕ Настройки.ui.Свойство("theme") Тогда
    Настройки.ui.Вставить("theme", Новый Структура());
КонецЕсли;

Если НЕ Настройки.ui.theme.Свойство("dark") Тогда
    Настройки.ui.theme.Вставить("dark", Истина);
КонецЕсли;
✅ С A1sDS (1 строка)
Настройки = Новый Структура();
A1sDS.GetOrInsertPath(Настройки, "ui.theme.dark", Истина);

// Создаст: {ui: {theme: {dark: Истина}}}

🔧 Как это работает

GetOrInsertPath() принимает:

  1. Структура — целевая структура (создайте заранее)
  2. Путь — строка вида "уровень1.уровень2.уровень3"
  3. Дефолт — значение, если путь не существует
  4. Разделитель (опционально) — по умолчанию "."
✨ Магия: автоматически создаёт промежуточные узлы-структуры.

💡 Примеры использования

1. ⚙️ Конфигурация приложения

Конфиг = Новый Структура();

A1sDS.GetOrInsertPath(Конфиг, "database.connection.timeout", 30);
A1sDS.GetOrInsertPath(Конфиг, "database.connection.pool_size", 10);
A1sDS.GetOrInsertPath(Конфиг, "logging.level", "info");
A1sDS.GetOrInsertPath(Конфиг, "logging.file.path", "C:\logs\app.log");

// Конфиг:
// {
//   database: {
//     connection: {
//       timeout: 30,
//       pool_size: 10
//     }
//   },
//   logging: {
//     level: "info",
//     file: {
//       path: "C:\logs\app.log"
//     }
//   }
// }

2. 💾 Кеш с автоинициализацией

КешОбъектов = Новый Структура();

// Первый вызов — создаст узел и вернёт дефолт
РегулярнаяВыражение = A1sDS.GetOrInsertPath(
    КешОбъектов,
    "regex.inn",
    Новый РегулярноеВыражение("^\d{10}(\d{2})?$")
);

// Повторный вызов — вернёт существующий объект
// (дефолт НЕ вставляется!)
РегулярнаяВыражение = A1sDS.GetOrInsertPath(
    КешОбъектов,
    "regex.inn",
    Новый РегулярноеВыражение("ДРУГОЙ_ПАТТЕРН") // ← не выполнится!
);
Важно: если путь уже существует, дефолтное значение не вставляется и не вычисляется. Это экономит ресурсы!

3. 👤 Пользовательские настройки

Пользователь = Новый Структура();

// Дефолтные настройки при первом входе
Язык = A1sDS.GetOrInsertPath(
    Пользователь,
    "preferences.language",
    "ru"
);

Тема = A1sDS.GetOrInsertPath(
    Пользователь,
    "preferences.ui.theme",
    "dark"
);

Размер = A1sDS.GetOrInsertPath(
    Пользователь,
    "preferences.ui.font_size",
    14
);

// Пользователь:
// {
//   preferences: {
//     language: "ru",
//     ui: {
//       theme: "dark",
//       font_size: 14
//     }
//   }
// }

👨‍👩‍👧 Семейство GetOrInsert

GetOrInsert() — базовая версия

Кеш = Новый Структура();

// Первый вызов — вставит и вернёт "дефолт"
Значение1 = A1sDS.GetOrInsert(Кеш, "ключ", "дефолт");
// Значение1 = "дефолт", Кеш.ключ = "дефолт"

// Повторный вызов — вернёт существующее
Значение2 = A1sDS.GetOrInsert(Кеш, "ключ", "другое");
// Значение2 = "дефолт" (НЕ "другое")

GetOrInsertEval() — ленивое вычисление Продвинуто

Кеш = Новый Структура();

// Дорогая операция выполнится только один раз
Regex = A1sDS.GetOrInsertEval(
    Кеш,
    "rxINN",
    "Новый РегулярноеВыражение(""^\d{10}(\d{2})?$"")"
);

// Повторный вызов — выражение НЕ вычисляется
Regex = A1sDS.GetOrInsertEval(
    Кеш,
    "rxINN",
    "ДорогаяФункция()" // ← не выполнится
);
Фишка: второй параметр — это строка с кодом, который вычисляется через Вычислить() только при первом вызове.

🎯 Use Cases

📊 Сравнение с аналогами

Язык Аналог
JavaScript _.set(obj, 'a.b.c', value) (lodash)
Python from addict import Dict; d['a']['b']['c'] = val
A1sDS.GetOrInsertPath(s, "a.b.c", val)

🚀 A1sDS — это lodash для 1С!