简体   繁体   中英

How to pass an array to a function without mutating the original array?

I'm working on a helper function within a bigger function.

I have an array of team object (each team looks like this {team: unique number of the team , points:0, goalDiff:0, goalsFor:0}) as the first argument of my function and I have an array of game results as a second argument (each game looks like this [number ref home team, number ref away team, goals scored by home team, goals scored by away team]).

My function looks at each game in the second array and allocate 2 points to the winning team and zero to the losing one. in case of draw, it allocates 1 point to each team. Function also counts the goals scored by each team.

    let computeGames = (arr, games) => {

  
    games.forEach((game) => {
      
      let homeTeamIndex = arr.findIndex(team => team.team === game[0])
      let awayTeamIndex = arr.findIndex(team => team.team === game[1])
      let homeTeam = arr[homeTeamIndex]
      let awayTeam = arr[awayTeamIndex]
    
      
      game[2] > game[3]
        ? (homeTeam.points += 2)
        : game[2] === game[3]
        ? ((homeTeam.points += 1), (awayTeam.points += 1))
        : (awayTeam.points += 2);
      homeTeam.goalsFor += game[2];
      awayTeam.goalsFor += game[3];
      homeTeam.goalDiff += game[2] - game[3];
      awayTeam.goalDiff += game[3] - game[2];
    });

  return arr
    
  };

My code is counting the points and goals as expected, but my issue is that when I execute something like the code below, the points are being counted in my teams array as well as in my doNotMutate array. I do not understand why teams is being mutated given it's a copy of teams that is passed to the function, not the teams array itself. If someone could explain, I'm getting really confused here.

Cheers

const teams = createTeams(number) // this is a helper function to generate my teams with all values = 0
let doNotMutate = [...teams]

doNotMutate= computeGames(doNotMutate,games)
  
  console.log(teams, doNotMutate)

Doing [...teams] does not copy the objects stored within the array. Each item of the array is simply copied into a new array. In your case each item is an object, meaning the new array will contain the exact same objects (think of them as "references to the same value" if that helps).

You can observe this:

teams[0] === doNotMutate[0] // true! (we don't want this)

You'll want to step through the array and map each item to a copy of itself ( {...obj} ). Something like this:

const doNotMutate = [...teams].map(game => ({...game}));

Alternatively, explore deep-clone implementations such as lodash's .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM