Search code examples
javascriptarraysnested-loops

Value in array is changed when I change a value in another array?


I have a problem where I'm having two arrays. Whenever I'm changing a value in one array with the code shown below, the other array do also get the same change which is not intended. If i copy and paste the code below in the javascript console in my browser I get the problem that originalArray is changed after I called ConvertDataArrayToLocationArray(dataArray)

let originalArray = [
  {
    "date": "2018-11-16",
    "type": "Entertainment",
    "location": "Oslo",
    "amount": 1024
  },
  {
    "date": "2018-11-16",
    "type": "Food",
    "location": "Oslo",
    "amount": 170
  },
  {
    "date": "2018-11-17",
    "type": "Food",
    "location": "Fredrikstad",
    "amount": 99
  },
  {
    "date": "2018-11-18",
    "type": "Food",
    "location": "Halden",
    "amount": 29
  },
  {
    "date": "2018-11-19",
    "type": "Entertainment",
    "location": "Oslo",
    "amount": 34
  },
  {
    "date": "2018-11-20",
    "type": "Entertainment",
    "location": "Oslo",
    "amount": 15
  },
  {
    "date": "2018-11-20",
    "type": "Food",
    "location": "Fredrikstad",
    "amount": 80
  },
  {
    "date": "2018-11-23",
    "type": "Transportation",
    "location": "Stavanger",
    "amount": 95
  },
  {
    "date": "2018-11-28",
    "type": "Entertainment",
    "location": "Oslo",
    "amount": 1024
  },
  {
    "date": "2018-11-29",
    "type": "Food",
    "location": "Oslo",
    "amount": 117.39
  },
  {
    "date": "2018-11-30",
    "type": "Transportation",
    "location": "Fredrikstad",
    "amount": 29
  },
  {
    "date": "2018-12-2",
    "type": "Transportation",
    "location": "Stavanger",
    "amount": 184
  },
  {
    "date": "2018-12-3",
    "type": "Entertainment",
    "location": "Oslo",
    "amount": 34
  },
  {
    "date": "2018-12-4",
    "type": "Food",
    "location": "Oslo",
    "amount": 162
  },
  {
    "date": "2018-12-4",
    "type": "Food",
    "location": "Fredrikstad",
    "amount": 231
  }
];

function ConvertDataArrayToLocationArray(dataArray) {

    let newArray = [];
    console.log("First dataArray[0].amount is the correct value. ");
    console.log(dataArray[0].amount);

    for(let i = 0; i < dataArray.length; i++) {

        let existed = false;

        for(let j = 0; j < newArray.length; j++) {

            if(dataArray[i].location === newArray[j].location) {

                newArray[j].amount = (newArray[j].amount + dataArray[i].amount);

                existed = true;

            }
        }


        if(!existed) {
            newArray.push(dataArray[i]); 

        }
    }

    console.log("Why is this dataArray[0].amount suddenly different?");
    console.log(dataArray[0].amount); 
    return newArray; 

}

let a = ConvertDataArrayToLocationArray(originalArray); 

My excepted outcome is that the variable called originalArray stays unchanged and I get a new array from the return value of ConvertDataArrayToLocationArray(dataArray).


Solution

  • When you are inserting an item into newArray, you are passing a reference to the object.

    So, any changes made to the item in new copied array newArray are reflected in the original array, and vice versa.

    To prevent this, instead of passing a reference, pass a copy of the object.

    newArray.push({...dataArray[i]}); 
    

    I'm using ES6 spread syntax to make a copy. We also have Object.assign() method and several others ways to clone an object.

    For your data, these would be enough because all properties are primitives. If there are object properties you have to use JSON.parse(JSON.stringify(dataArray[i])) or other methods.