【问题标题】:finding count of objects inside array changes the array itself在数组中查找对象的数量会改变数组本身
【发布时间】:2020-10-08 21:34:44
【问题描述】:

我有一个关于在数组中查找对象计数的问题。 我的数组是这样的:

completePositions: any = [
    {
      totalPositions: [
        { position: "CNA", count: 2 },
        { position: "LVN", count: 5 },
        { position: "RNA", count: 8 }
      ]
    },
    {
      totalPositions: [
        { position: "CNA", count: 13 },
        { position: "LVN", count: 11 },
        { position: "RNA", count: 15 }
      ]
    }
  ];

我试图在 totalPositions 数组中找到每个位置的总数,这样我的最终数组将如下所示:

totalPositionsCount = [
        { position: "CNA", count: 15 },
        { position: "LVN", count: 16 },
        { position: "RNA", count: 23 }
  ];

我创建了一个函数来对“totalPositons”数组中的每个位置求和并将总和推送到totalPositionsCount。我的函数完成了这项工作,我得到了总数,但它改变了父数组“completePositions”,并且“completePositions”的第一个“totalPositions”被“totalPositionsCount”数组替换。我尝试创建“completePositions”的备份并将其用于计算,但两个数组第一个“totalPositions”仍然被“totalPositionsCount”数组替换。

我总结位置的函数是:

codeToShowTotalResources() {
    for (let totPos of this.completePositions) {
        for (let eachPos of totPos.totalPositions) {
            console.log("eachPos", eachPos);

            let postCountIndex = this.totalPositionsCount.findIndex(
                pos => pos.position == eachPos.position
            );

            if (postCountIndex != -1) {
                console.log("Already exists, sum up positions");
                let positionCount = this.totalPositionsCount[postCountIndex].count + eachPos.count;
                this.totalPositionsCount[postCountIndex].count = positionCount;
            } else {
                console.log("Add it for first time");
                this.totalPositionsCount.push(eachPos);
            }
        }

    }
}

如果我用this.totalPositionsCount[postCountIndex] = { position: eachPos.position, count: positionCount }; 替换this.totalPositionsCount[postCountIndex].count = positionCount;,那么它工作得很好。我想知道我做错了什么,或者它应该以这种方式工作。

我在stackblitz 中打开了一个示例项目 任何帮助都会很棒:)

【问题讨论】:

    标签: javascript arrays typescript


    【解决方案1】:

    当您这样做时:this.totalPositionsCount.push(eachPos)eachPos 变量代表来自completePositions 的条目。所以现在this.totalPositionsCountthis.completePositions 引用了同一个对象。如果您修改该对象,则更改会显示在两个位置,因为它是同一个对象。

    这是使用reduceforEach 的替代方法:

    const completePositions = [
      {
        totalPositions: [
          {position: "CNA", count: 2},
          {position: "LVN", count: 5},
          {position: "RNA", count: 8}
        ]
      },
      {
        totalPositions: [
          {position: "CNA", count: 13},
          {position: "LVN", count: 11},
          {position: "RNA", count: 15}
        ]
      }
    ];
    
    const totals = completePositions
      .map(x => x.totalPositions)
      .reduce((acc, totalPositions) => {
        totalPositions.forEach(({position, count}) => {
          acc[position] = (acc[position] || 0) + count;
        })
        return acc;
      }, {})
      
    console.log(totals);

    【讨论】:

    • 所以当我写 let copyOfArray = parentArray 时,它不是创建 parentArray 的副本,而是创建对 parentArray 的引用,并且我对副本数组所做的每个计算也会反映在父数组中.感谢您的回答和干净的替代方法。
    • 正确。在这种情况下,copyOfArray 和 parentArray 指向同一个数组,并且更改将反映在两个位置。
    • 最简单的方法是通过spread operator:const newArray = [...oldArray]。但是请注意,如果数组包含对其他对象的引用,这些对象仍将被链接。换句话说,您将拥有两个可以独立修改的数组,但它们的内容可能仍包含对公共/共享对象的引用。如果需要创建嵌套数组和对象的完全独立副本,有ways to do that
    • 感谢您的帮助:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-16
    相关资源
    最近更新 更多