Search code examples
arraysreactjsloopsjavascript-objects

How to add new property to an existing javascript object


I try to add new property "id" to an array of object. The reson I don't to this in the begining is because first I have to sort the array in a random order. I try to do this with a loop, alse with forEach, but it doesn't work. Why?

    CreateCardList = () => {
        const { cardsAmount } = this.state;
        let halfList = [];
        let card = {};
        for (let i = 0; i < cardsAmount/2; i++) { // choose cards for half of the amount
            card = {
                type: 'hero',
                isHidden: true
            }
            halfList.push(card);
        }
        let entireCardList = [...halfList, ...halfList]; // duplicate the array
        entireCardList.sort((a, b) => 0.5 - Math.random()); // sorting the array in random order
        for (let j = 0; j < entireCardList.length; j++) {
            entireCardList[j].id = j;
        }
        console.log(entireCardList);
    }

In the console I got the below array. If I refrush, the id numbers change but still it is not ordered.

0: {type: "hero", isHidden: true, id: 9}
1: {type: "hero", isHidden: true, id: 7}
2: {type: "hero", isHidden: true, id: 10}
3: {type: "hero", isHidden: true, id: 5}
4: {type: "hero", isHidden: true, id: 11}
5: {type: "hero", isHidden: true, id: 5}
6: {type: "hero", isHidden: true, id: 8}
7: {type: "hero", isHidden: true, id: 7}
8: {type: "hero", isHidden: true, id: 8}
9: {type: "hero", isHidden: true, id: 9}
10: {type: "hero", isHidden: true, id: 10}
11: {type: "hero", isHidden: true, id: 11}

Solution

  • Your problem comes from this line: let entireCardList = [...halfList, ...halfList];
    You are trying to create a completly new array by thinking that you are duplicating the halfList, but what is instead happening; the spread operator will not create a deep copy of array so it is just shallow copied. And when you assign a id to one item from the list, it is actually assigned to multiple, since they have the same reference.

    one solution replace this: let entireCardList = [...halfList, ...halfList]; with:

    const firstHalf = JSON.parse(JSON.stringify(halfList));
    const secondHalf = JSON.parse(JSON.stringify(halfList));
    let entireCardList = [...firstHalf, ...secondHalf];
    

    And it should work as expected :)

    Working example:

    const cardsAmount = 6
    const halfList = [];
    
    for (let i = 0; i < cardsAmount / 2; i++) {
      halfList.push({ type: 'hero', isHidden: true });
    }
    
    const firstHalf = JSON.parse(JSON.stringify(halfList));
    const secondHalf = JSON.parse(JSON.stringify(halfList));
    const entireCardList = [...firstHalf, ...secondHalf];
    
    // If cards are the same, then there is no point in sorting...
    entireCardList.sort((a, b) => 0.5 - Math.random());
    
    for (let j = 0; j < entireCardList.length; j++) {
      entireCardList[j].id = j;
    }
    
    console.log(entireCardList);