-1

I google a lot about this and i understand that there is ways of copying arrays and use them without affecting the original one but i did have tried a lot of things and nothing seems to work on my specific lines of code.

I'm doing a simple memory game. When the user gets the pair correct, it would appear the image of the matched pair on a right screen showing all the matched images that user got. The image below shows that, but when i'm using a method to resize the image (pairs matched are smaller than the normal game cards), i get the card selected with a undefined cardState.

enter image description here

Here is a bunch of code that may help you figuring out my problem:

   checkCardSelection(_cardSelectionArray,_position){
    var _cardArray = this.state.cardArray;
    var _matchedcardArray = this.state.matchedcardArray;
    console.log("Position:" +_position)
    if(_cardSelectionArray[0].cardType === _cardSelectionArray[1].cardType){
        var copy = _cardSelectionArray.slice(0,1)
        _matchedcardArray.push(copy)
       _matchedcardArray[_matchedcardArray.length-1].cardState = this.renderMatchedImage(_matchedcardArray[_matchedcardArray.length-1].cardType)
 this.setState({ cardArray: _cardArray, matchedcardArray: _matchedcardArray });


renderMatchedImage(cardType) {
switch(cardType) {
case 'A':
  return <img src={imagem1} alt="Raposa" width="49px" height="70px"/>;
case 'B':
  return <img src={imagem2} alt="Cobra" width="49px" height="70px"/>;
case 'C':
  return <img src={imagem3} alt="Galinha" width="49px" height="70px"/>;
        // and so on...

MatchedCardArray is an empty array that will get cards as soon as they get paired up

CardSelectionArray is a double value array with the two pairs selected

Each card has a CardType (A,B,C,D,...) and a CardState ("Invisible" or the returned image). They are randomized with a funcion. For example the CardArray may be:

0: {cardType: "G", cardState: "INVISIBLE"}
1: {cardType: "B", cardState: "INVISIBLE"}
2: {cardType: "A", cardState: "INVISIBLE"}
Telmo Pina
  • 51
  • 8
  • What you want is not a copy of an array, which is easy enough, but a deep copy -- you want each element of the new array to be a copy of each element of the previous array. Right? – TKoL Nov 07 '19 at 17:16
  • What are the data structures in your array? Is the array just an array of plain objects? Or are they class instances? – TKoL Nov 07 '19 at 17:17
  • 2
    Prefixing all variables and parameters with underscore is inefficient and reduces readability. Underscore prefixes in JavaScript should be used to mark object or class properties as "private" - or at least discourage the end user from using them. In a function header or body, it serves you no purpose. – Klaycon Nov 07 '19 at 17:17
  • If you want to copy and change the copy without altering the original one use `splice` : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice – Pritam Banerjee Nov 07 '19 at 17:18
  • 1
    Possible duplicate of [What is the most efficient way to deep clone an object in JavaScript?](https://stackoverflow.com/questions/122102/what-is-the-most-efficient-way-to-deep-clone-an-object-in-javascript) – Ruzihm Nov 07 '19 at 17:21
  • `let copy = [...original]` – junvar Nov 07 '19 at 17:22
  • @TKoL updated the question. Is that clear now? – Telmo Pina Nov 07 '19 at 17:32
  • 1
    Still seems fairly clear that you want a deep copy. You want to copy the array, and you want each element in the new array to be a copy of what was in the old array. I think if you figure out how to deep copy, your problem will be solved – TKoL Nov 07 '19 at 17:34
  • @TKoL Thanks, you helped me solving :) – Telmo Pina Nov 07 '19 at 17:39

2 Answers2

2

There is no standard way to deep copy an array of objects in JavaScript as far as I know. If you need to do a deep copy of an array containing "simple" objects (simple meaning no functions etc.), you can do it with this simple trick:

const newArray = oldArray.map(item => JSON.parse(JSON.stringify(item)));

To copy an array of primitives, you can use even simpler:

const newArray = oldArray.slice();

UPDATE (after discussion in comments):

If you need to copy an array of shallow objects (all properties pointing to primitive values), the following way might give you a better performance than JSON.parse/stringify:

const newArray = oldArray.map(item => Object.assign({}, item));
ajobi
  • 2,996
  • 3
  • 13
  • 28
  • 1
    I think he's using shallow objects as well, so `Object.assign({}, item)` would also work, and would be marginally more performant. – TKoL Nov 07 '19 at 17:34
  • I like your point ! For small amounts of data I usually don't take performance into consideration (only if by accident :D). Have you also run some tests on this or can you point me to some resource ? – ajobi Nov 07 '19 at 17:41
  • No tests, I'm just sure that it is faster than `JSON.parse(JSON.stringify())`. Maybe I'm a bit overconfident, but I definitely have the feeling that taking an object, turning it into a string, and turning it back into an object from parsing the string takes more resources than just copying a basic object into another object. `Object.assign()` is almost definitely going to be fairly optimized and doesn't involve any translation stage – TKoL Nov 07 '19 at 17:44
  • Yes, should work like that. I would not be surprised if `JSON.parse()` used `Object.assign()` itself.. I will add this point to the answer for completeness! – ajobi Nov 07 '19 at 18:05
0

you can easily do that using es6 feature

let variable=[...yourarray]
DEEPAK
  • 1,364
  • 10
  • 24