【问题标题】:How to pass an array to a function without mutating the original array?如何在不改变原始数组的情况下将数组传递给函数?
【发布时间】:2020-11-16 15:38:52
【问题描述】:

我正在一个更大的函数中处理一个辅助函数。

我有一个团队对象数组(每个团队看起来像这样 {team:unique number of the team, points:0, goalDiff:0, targetsFor:0})作为我函数的第一个参数,我有一个游戏数组结果作为第二个参数(每场比赛看起来像这样 [编号 ref 主队,编号 ref 客队,主队进球数,客队进球数])。

我的函数查看第二个数组中的每场比赛,并将 2 分分配给获胜的球队,将 0 分分配给失败的球队。在平局的情况下,它为每支球队分配1分。函数还会统计每支球队的进球数。

    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
    
  };

我的代码按预期计算分数和目标,但我的问题是,当我执行类似下面的代码时,我的团队数组和 doNotMutate 数组中的分数都被计算在内。 我不明白为什么团队会发生变异,因为它是传递给函数的团队副本,而不是团队数组本身。如果有人能解释一下,我真的很困惑。

干杯

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)

【问题讨论】:

  • 请给出输入和预期输出
  • 执行[...teams] 不会复制存储在数组中的对象。您需要逐步遍历数组并将每个项目映射到 {...obj}(即 [...teams].map(g=>({...g})))或探索深度克隆实现。
  • 对象总是“通过引用传递”,因此尽管您使用扩展运算符执行浅拷贝,但对对象属性所做的修改将反映在原始列表和复制列表中。
  • 谢谢詹姆斯,我会试试的。那么目前我的数组中的内容仍然是对原始对象的引用吗?无论它们位于哪个数组中?
  • 是的。您可以深度克隆对象或编写函数,这样它就不会改变列表。我会推荐后者。

标签: javascript arrays function mutation


【解决方案1】:

执行[...teams] 不会复制存储在数组中的对象。数组的每一项都被简单地复制到一个新数组中。在您的情况下,每个项目都是一个对象,这意味着新数组将包含完全相同的对象(如果有帮助,可以将它们视为 “对相同值的引用”)。

你可以观察到:

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

您需要遍历数组并将每个项目映射到其自身的副本 ({...obj})。像这样的:

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

或者,探索深度克隆实现,例如 lodash's

【讨论】:

    猜你喜欢
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    • 2012-03-24
    • 2021-06-09
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 2019-10-26
    相关资源
    最近更新 更多