Почему действия в объединенном массиве влияют на оба массива после изменений?

#javascript #node.js #arrays #concatenation

#javascript #node.js #массивы #конкатенация

Вопрос:

Я запускаю процесс ниже, чтобы собрать все атрибуты продукта и параметры из объекта, чтобы обновить продукт.

По какой-то странной причине основные каталоги категорий массива изменяются, и я, похоже, не могу понять, почему.

После следующего процесса categoryUrls[random key].attributes.options добавляются новые значения.

 const {categoryUrls} = require('./helpers/categoryUrls.js')

getCategory = function (categoryUrls) {

    let att = []
    
    for (const key in categoryUrls) {
        if (categoryUrls[key].attributes) {// check if has attribute 
            att = att.concat(categoryUrls[key].attributes)
            
            for(var i=0; i<att.length;   i) {// check if attribute ID already exist and remove duplicates
                for(var j=i 1; j<att.length;   j) {
                    if(att[i].id === att[j].id){
                        for (let k = 0; k < att[j].options.length; k  ) { // if attribute ID already exist unite options
                            let exist = att[i].options.find(option => option == att[j].options[k]) // check if option no already exist 
                            if (!exist) {
                                att[i].options.push(att[j].options[k])
                            }
                        }
                        att.splice(j--, 1);
                    }
                }
            }
        }
    }
    return att
}


let data = getCategory(categoryUrls)
productData = productData.concat(data)
  

Ответ №1:

Если я понял, вы пытаетесь сохранить новый массив в att , но оставить исходный неизмененным, но вы применяете процесс прямо к categoryUrls. Это правильно? Если это так, помните, что массивы являются ссылочными типами, поэтому, если вы работаете с ними, вы изменяете фактический массив, они не работают как строки или целые числа.

Попробуйте скопировать массив перед его обработкой и применить процесс к его копии.

Попробуйте это:

 const {categoryUrls} = require('./helpers/categoryUrls.js')

getCategory = function (categoryUrls) {

    let newArray = [...categoryUrls]

    let att = []
    
    for (const key in categoryUrls) {
        if (categoryUrls[key].attributes) {// check if has attribute 
            att = att.concat(newArray[key].attributes)
            
            for(var i=0; i<att.length;   i) {// check if attribute ID already exist and remove duplicates
                for(var j=i 1; j<att.length;   j) {
                    if(att[i].id === att[j].id){
                        for (let k = 0; k < att[j].options.length; k  ) { // if attribute ID already exist unite options
                            let exist = att[i].options.find(option => option == att[j].options[k]) // check if option no already exist 
                            if (!exist) {
                                att[i].options.push(att[j].options[k])
                            }
                        }
                        att.splice(j--, 1);
                    }
                }
            }
        }
    }
    return att
}


let data = getCategory(categoryUrls)
productData = productData.concat(data)
  

Комментарии:

1. я думаю, что [… a .. b ..] — это то же самое, что метод concat. Я думаю, что проблема также в том, что массив содержит объекты. Как вы сказали, это не похоже на строку и числа. так что это [… a .. b ..] также не будет работать.