невозможно обновить массив без обновления другого массива внутри graalvm

Вопрос или проблема

Почему это обновляет два массива сразу, когда я обновил только один?

Я попробовал оператор распаковки при установке массивов из оригинального массива. Я пробовал использовать цикл for и заполнять массив отдельно. Не знаю, что происходит.

Я не видел информации на Stack Overflow о GraalVM и массивах, которые не копируются. ChatGPT/Claude тоже не знают.

код1:

    s.print("sys_imported_saved_configuration_id: " + sys_imported_saved_configuration_id);
                            const sys_imported_saved_configuration_data = new SysRecord({
                                sys_table_name: 'sys_imported_saved_configuration_data',
                                where: [
                                    [{
                                        "sys_column": "sys_imported_saved_configuration_id",
                                        "sys_operator": "=",
                                        "sys_value": sys_imported_saved_configuration_id
                                    }]
                                ],
                                select_columns: ['sys_id', 'sys_data', 'sys_operation']
                            });

                            const is_data_available = await sys_imported_saved_configuration_data.query();

код2:


class SysRecord {
    constructor({ sys_table_name, select_columns = null, where = null, where_sys_id = null, sort_column = null, sort_direction = null }) {
        this.sys_table_name = sys_table_name;
        this.select_columns = select_columns || [];
        this.where = where || {};
        this.where_sys_id = where_sys_id;
        this.sort_column = sort_column;
        this.sort_direction = sort_direction;
        this.results = [];
        this.currentIndex = -1;
        this.originalResults = []; // Для отслеживания оригинальных записей
    }

    toMap() {
        const queryParams = {};
        if (this.sys_table_name) queryParams['sys_table_name'] = this.sys_table_name;
        if (this.select_columns.length > 0) queryParams['select_columns'] = JSON.stringify(this.select_columns);
        if (Object.keys(this.where).length > 0) queryParams['where'] = JSON.stringify(this.where);
        if (this.where_sys_id) queryParams['where_sys_id'] = this.where_sys_id;
        if (this.sort_column) queryParams['sort_column'] = this.sort_column;
        if (this.sort_direction) queryParams['sort_direction'] = this.sort_direction;
        return queryParams;
    }

    async query() {
        s.print("\n\nquery()");
        // Проверить и добавить sys_id и sys_table_name в select_columns, если они отсутствуют
        if (!this.select_columns.includes('sys_id')) {
            this.select_columns.push('sys_id');
        }
        if (!this.select_columns.includes('sys_table_name')) {
            this.select_columns.push('sys_table_name');
        }

        // Выполнить запрос
        const records = await s.get(this.toMap());
        s.print("RECORDS: "+records);

        for( var record of records){
            s.print("record: "+record);

              this.originalResults.push(record);
              this.results.push(record);

        }

        s.print("originalResults: "+this.originalResults);
        s.print("results: "+this.results);

        this.currentIndex = 0;

        this.set('sys_create',true);

        s.print("\noriginalResults2: "+this.originalResults);
        s.print("results2: "+this.results);

        return this.results.length > 0;
    }

    get(fieldName) {
        if (this.currentIndex >= 0 && this.currentIndex < this.results.length) {
            return this.results[this.currentIndex][fieldName];
        }
        return null;
    }

    set(fieldName, value) {
        if (this.currentIndex >= 0 && this.currentIndex < this.results.length) {
            this.results[this.currentIndex][fieldName] = value;
        }
    }

}

Ответ или решение

Проблема, с которой вы столкнулись, связана с тем, как JavaScript обрабатывает ссылки на объекты и массивы. Когда вы добавляете объект в массив (например, this.results и this.originalResults), оба массива ссылаются на один и тот же объект. Таким образом, изменения, внесенные в одну из коллекций, будут также отражаться в другой.

В вашей реализации, когда вы выполняете следующие строки кода:

this.originalResults.push(record);
this.results.push(record);

Вы фактически добавляете один и тот же объект record в два массива. Из-за этого при изменении объекта в одном из массивов, изменения также будут видны в другом, так как оба массива ссылаются на один и тот же экземпляр объекта.

Решение

Чтобы решить эту проблему, вы должны создавать копии объектов перед их добавлением в массивы. Вы можете сделать это несколькими способами. Один из самых простых способов — использовать оператор распространения (spread operator), чтобы создать глубокую копию объекта. Однако, поскольку record может быть вложенным объектом, вам может потребоваться использовать метод, который создает глубокую копию.

Вот обновленный фрагмент кода для метода query():

for (var record of records) {
    s.print("record: " + record);

    // Создаем глубокую копию объекта record
    this.originalResults.push(JSON.parse(JSON.stringify(record)));
    this.results.push(JSON.parse(JSON.stringify(record)));
}

Альтернативное решение

Если ваши объекты record не слишком сложные и не содержат методов или функций, вы можете использовать оператор распространения:

for (var record of records) {
    s.print("record: " + record);

    // Копируем объект с помощью оператора распространения
    this.originalResults.push({...record});
    this.results.push({...record});
}

Замечания

  1. Производительность: Имейте в виду, что оба метода, описанные выше, могут иметь накладные расходы на производительность, особенно для больших наборов данных. Используйте их с осторожностью в зависимости от вашего контекста.

  2. Типы данных: Учтите, что JSON-сериализация не будет работать с функциями и некоторыми другими типами данных, такими как Date. Если ваши объекты могут содержать такие данные, вам может понадобиться другой подход для создания глубоких копий.

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

Оцените материал
Добавить комментарий

Капча загружается...