0

I have an array I want to use as base array of my work, and each time a unction calls I want it to be cloned to prevent changing the base one, but it doesn't work I don't know why and I tried all other solutions else where

this is my code:

const baseArray = [
    {
        english: {
            name: "test1 english",
            description: "test1 english"
        },
        spanish: {
            name: "test1 spanish",
            description: "test1 spanish"
        }
    }
];


function removeSpanish() {

    // showing base array before work
    console.log(baseArray); // expected to log the baseArray, but logs the edited array


    // cloning the array
    var result = [...baseArray];

    // checking if passed by value or passed by reference
    console.log(result[0] === baseArray[0]); // expected to log false, but it logs true

    // removing other language details from each collection
    result.map(collection => {
        delete collection['spanish'];
        return collection;
    });


    // showing base array after work
    console.log(baseArray); // expected to log the baseArray, but logs the edited array


    return result;
}

export { find };

and what surprises me is that even the first
console.log(baseArray)

shows the edited one.
and the

console.log(result[0] === baseArray[0]);

logs true so they are passed by refference
i also tried these 2 other approaches but none of them worked

var result = baseArray.splice();
var result = Array.from(baseArray);

NOTE: i use this in react and it will be excuted each time a state changes, I don't know if it causes the problem

  • 4
    You're only producing a shallow copy of your array. Lodash has a clonedeep method, or you could implement your own to reduce bundle size. If your objects are serializable, `JSON.parse(JSON.stringify(result))` Is a common shortcut. [More info](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript?rq=1) – Charlie Bamford Apr 14 '21 at 19:12
  • 1
    @CharlesBamford has explained why this isn't working, but as a stylistic point, you should really use `forEach` rather than `map` when you're just mutating the array and not returning any result, as here. `map` is for building a new array by applying a (pure) function to each element, `forEach` is for just "doing something" with each element where you don't care about anything being returned. – Robin Zigmond Apr 14 '21 at 19:16
  • thank you so much @CharlesBamford , it worked – efwefjiopefjsfh Apr 14 '21 at 19:20
  • @RobinZigmond thanks for you 2, i will use it – efwefjiopefjsfh Apr 14 '21 at 19:20

1 Answers1

0

thanks to Charles Bamford that suggested using lodash's cloneDeep, and thanks to Robin Zigmond that suggested using forEach instead of map

so i updated my code to this and it worked:

const _ = require('lodash');

const baseArray = [
    {
        english: {
            name: "test1 english",
            description: "test1 english"
        },
        spanish: {
            name: "test1 spanish",
            description: "test1 spanish"
        }
    }
];


function removeSpanish() {

    // showing base array before work
    console.log(baseArray); 


    // cloning the array
    var result = _.cloneDeep(Collections);

    // checking if passed by value or passed by reference
    console.log(result[0] === baseArray[0]); 

    // removing other language details from each collection
    result.forEach(collection => {
        delete collection['spanish'];
        return collection;
    });


    // showing base array after work
    console.log(baseArray); 


    return result;
}

export { find };

you can read more about lodash here