首页 > 解决方案 > Angular/TypeScript Map 使用每个对象的最后一个索引

问题描述

我正在尝试创建一个包含 120 个对象的数组(地图的十六进制),然后为每个对象添加信息。

当我使用地图时,id 应该是当前对象的索引,我可以按预期控制台记录正确的当前索引,但由于某种原因,每个对象的 id 都是 119。我查看了其他一些地图这里和Mozilla的例子,我不明白我哪里出错了。

export class MapComponent implements OnInit {

  arrayOfObjects = Array(120).fill({})
  hexTiles = this.arrayOfObjects.map( (hex, index) => this.createHex(hex, index))

  constructor() { }

  ngOnInit() {
  }

  createHex(hex, index){
    console.log('Current Index', index)
    hex['id'] = index
    hex['x-coordinate'] = null
    hex['y-coordinate'] = null
    hex['mapped'] = false
    hex['terrain'] = ''
    hex['details'] = ''

    return hex
  }

}

更新 我尝试了一个建议的解决方案,但现在得到了一个包含 120 个空对象的数组。这是更新的代码:

HTML:这不显示任何内容。

<div>
  <div *ngFor="let hex of hexTiles; let i = index">
    <pre>
      {{hex}}
    </pre>
  </div>
</div>

TS:这将控制台记录“Hexs (120) [empty × 120]”

export class MapComponent implements OnInit {

  hexTiles = [...Array(120)].map((_, i) => this.createHex({}, i));


  constructor() { }

  ngOnInit() {
    console.log('Hexs', this.hexTiles);
  }

  createHex(hex, index) {
    hex['id'] = index;
    hex['x-coordinate'] = null;
    hex['y-coordinate'] = null;
    hex['mapped'] = false;
    hex['terrain'] = '';
    hex['details'] = '';
    return hex;
  }

}

标签: javascriptangulartypescriptindexing

解决方案


改变

arrayOfObjects = Array(120).fill({})
hexTiles = this.arrayOfObjects.map( (hex, index) => this.createHex(hex, index))

为了这

hexTiles = [...Array(120)].map((_, i) => this.createHex({}, i));

这是一个工作片段:

function createHex(hex, index) {
    hex['id'] = index;
    hex['x-coordinate'] = null;
    hex['y-coordinate'] = null;
    hex['mapped'] = false;
    hex['terrain'] = '';
    hex['details'] = '';
    return hex;
}

const hexTiles = [...Array(120)].map((_, i) => createHex({}, i));

console.log(hexTiles);

这是您的问题的解释

function createHex(hex, index) {
    hex['id'] = index;
    hex['x-coordinate'] = null;
    hex['y-coordinate'] = null;
    hex['mapped'] = false;
    hex['terrain'] = '';
    hex['details'] = '';
    return hex;
}
const obj = { };
const arrayOfObjects = Array(120).fill(obj);
const hexTilesBad = arrayOfObjects.map((hex, index) => createHex(hex, index));
console.log(obj)

当用 {} 填充数组时,实际上是用对同一对象的引用的副本填充它。这是因为,默认情况下,在 Javascript/Typescript 中,当您分配对象时,您会分配其引用。

在上面的例子中,我们没有用 填充数组,而是用{}填充它obj,也就是{}。当我们console.log(obj)结束时,我们看到它确实具有最后一次迭代的值。

它的引用在数组中被复制了 120 次,这些引用被传递给map, 然后传递给你的createHex函数。所以最终,你只是修改了同一个对象 120 次。

但是,当您{}直接createHexmap箭头函数传递到时,会为函数范围内的每次迭代创建一个新对象,因此不会共享任何内容。

编辑: [...Array(120)]似乎在 TypeScript 中不起作用。正如@AJT_82 在下面的评论中指出的那样,这是由于TypeScript 错误导致此扩展运算符技巧错误地转换为 JavaScript。

为了规避这个问题,您可以尝试以下方法:

Array.from({ length: 120 })

或坚持你的方法

Array(120).fill({})

重要的是不要使用这个数组的内容,因为它们只是对同一个对象的引用。


推荐阅读